nanocoap.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2016-2018 Kaspar Schleiser <kaspar@schleiser.de>
3  * SPDX-FileCopyrightText: 2018 Freie Universität Berlin
4  * SPDX-FileCopyrightText: 2018 Inria
5  * SPDX-FileCopyrightText: 2018 Ken Bannister <kb2ma@runbox.com>
6  * SPDX-License-Identifier: LGPL-2.1-only
7  */
8 
9 #pragma once
10 
76 #include <assert.h>
77 #include <errno.h>
78 #include <stdint.h>
79 #include <stdbool.h>
80 #include <stddef.h>
81 #include <string.h>
82 #include <unistd.h>
83 
84 #include "bitarithm.h"
85 #include "bitfield.h"
86 #include "byteorder.h"
87 #include "iolist.h"
88 #include "macros/utils.h"
89 #include "modules.h"
90 #include "net/coap.h"
91 #include "net/sock/udp.h"
92 
93 #if defined(MODULE_NANOCOAP_RESOURCES)
94 #include "xfa.h"
95 #endif
96 
97 #ifdef __cplusplus
98 extern "C" {
99 #endif
100 
106 #define COAP_GET (0x01)
107 #define COAP_POST (0x02)
108 #define COAP_PUT (0x04)
109 #define COAP_DELETE (0x08)
110 #define COAP_FETCH (0x10)
111 #define COAP_PATCH (0x20)
112 #define COAP_IPATCH (0x40)
113 #define COAP_IGNORE (0xFF)
115 #define COAP_MATCH_SUBTREE (0x8000)
122 #define COAP_FORMAT_NONE (UINT16_MAX)
123 
131 #ifndef CONFIG_NANOCOAP_NOPTS_MAX
132 #define CONFIG_NANOCOAP_NOPTS_MAX (16)
133 #endif
134 
139 #ifndef CONFIG_NANOCOAP_URI_MAX
140 #define CONFIG_NANOCOAP_URI_MAX (64)
141 #endif
142 
146 #ifndef CONFIG_NANOCOAP_BLOCK_SIZE_EXP_MAX
147 #define CONFIG_NANOCOAP_BLOCK_SIZE_EXP_MAX (6)
148 #endif
149 
153 #ifndef CONFIG_NANOCOAP_BLOCKSIZE_DEFAULT
154 #define CONFIG_NANOCOAP_BLOCKSIZE_DEFAULT COAP_BLOCKSIZE_64
155 #endif
156 
158 #ifndef CONFIG_NANOCOAP_QS_MAX
159 #define CONFIG_NANOCOAP_QS_MAX (64)
160 #endif
168 #ifndef CONFIG_NANOCOAP_BLOCK_HEADER_MAX
169 #define CONFIG_NANOCOAP_BLOCK_HEADER_MAX (80)
170 #endif
171 
179 #define COAP_OPT_FINISH_NONE (0x0000)
181 #define COAP_OPT_FINISH_PAYLOAD (0x0001)
187 typedef struct __attribute__((packed)) {
188  uint8_t ver_t_tkl;
189  uint8_t code;
190  uint16_t id;
191 } coap_hdr_t;
192 
196 typedef struct {
197  uint16_t opt_num;
198  uint16_t offset;
199 } coap_optpos_t;
200 
218 typedef struct {
220  uint8_t *payload;
222  uint16_t payload_len;
223  uint16_t options_len;
226 #ifdef MODULE_GCOAP
227  uint32_t observe_value;
228 #endif
229 } coap_pkt_t;
230 
235 
258 typedef ssize_t (*coap_handler_t)(coap_pkt_t *pkt, uint8_t *buf, size_t len,
259  coap_request_ctx_t *context);
260 
273 typedef int (*coap_blockwise_cb_t)(void *arg, size_t offset, uint8_t *buf, size_t len, int more);
274 
285 typedef int (*coap_request_cb_t)(void *arg, coap_pkt_t *pkt);
286 
292 typedef uint16_t coap_method_flags_t;
293 
297 typedef struct {
298  const char *path;
301  void *context;
303 
307 typedef const struct {
309  const size_t resources_numof;
311 
319 
327 #if defined(MODULE_SOCK_AUX_LOCAL) || DOXYGEN
329 #endif
330 #if defined(MODULE_GCOAP) || DOXYGEN
337  uint32_t tl_type;
338 #endif
339 };
340 
341 /* forward declarations */
342 static inline uint8_t *coap_hdr_data_ptr(const coap_hdr_t *hdr);
343 static inline size_t coap_hdr_get_token_len(const coap_hdr_t *hdr);
344 static inline const void * coap_hdr_get_token(const coap_hdr_t *hdr);
345 
354 
363 
373 
383 
393 
397 typedef struct {
398  size_t offset;
399  uint32_t blknum;
400  uint8_t szx;
401  int8_t more;
403 } coap_block1_t;
404 
408 typedef struct {
409  size_t start;
410  size_t end;
411  size_t cur;
412  uint8_t *opt;
414 
415 #if defined(MODULE_NANOCOAP_RESOURCES) || DOXYGEN
421 #define NANOCOAP_RESOURCE(name) \
422  XFA_CONST(coap_resource_t, coap_resources_xfa, 0) CONCAT(coap_resource_, name) =
423 #else
429 extern const coap_resource_t coap_resources[];
430 
436 extern const unsigned coap_resources_numof;
437 #endif
438 
453 static inline uint8_t coap_code(unsigned cls, unsigned detail)
454 {
455  return (cls << 5) | detail;
456 }
457 
465 static inline unsigned coap_get_code_class(const coap_pkt_t *pkt)
466 {
467  return pkt->hdr->code >> 5;
468 }
469 
477 static inline unsigned coap_get_code_detail(const coap_pkt_t *pkt)
478 {
479  return pkt->hdr->code & 0x1f;
480 }
481 
489 static inline unsigned coap_get_code_decimal(const coap_pkt_t *pkt)
490 {
491  return (coap_get_code_class(pkt) * 100) + coap_get_code_detail(pkt);
492 }
493 
501 static inline unsigned coap_get_code_raw(const coap_pkt_t *pkt)
502 {
503  return (unsigned)pkt->hdr->code;
504 }
505 
513 static inline coap_method_t coap_get_method(const coap_pkt_t *pkt)
514 {
515  return pkt->hdr->code;
516 }
517 
525 static inline unsigned coap_get_id(const coap_pkt_t *pkt)
526 {
527  return ntohs(pkt->hdr->id);
528 }
529 
540 static inline unsigned coap_get_token_len(const coap_pkt_t *pkt)
541 {
542  return coap_hdr_get_token_len(pkt->hdr);
543 }
544 
552 static inline void *coap_get_token(const coap_pkt_t *pkt)
553 {
554  return coap_hdr_data_ptr(pkt->hdr);
555 }
556 
566 static inline unsigned coap_get_total_len(const coap_pkt_t *pkt)
567 {
568  return (uintptr_t)pkt->payload - (uintptr_t)pkt->hdr + pkt->payload_len;
569 }
570 
581 static inline unsigned coap_get_type(const coap_pkt_t *pkt)
582 {
583  return (pkt->hdr->ver_t_tkl & 0x30) >> 4;
584 }
585 
593 static inline unsigned coap_get_ver(const coap_pkt_t *pkt)
594 {
595  return (pkt->hdr->ver_t_tkl & 0x60) >> 6;
596 }
597 
608 static inline uint8_t coap_hdr_tkl_ext_len(const coap_hdr_t *hdr)
609 {
610  if (!IS_USED(MODULE_NANOCOAP_TOKEN_EXT)) {
611  return 0;
612  }
613 
614  switch (hdr->ver_t_tkl & 0xf) {
615  case 13:
616  return 1;
617  case 14:
618  return 2;
619  case 15:
620  assert(0);
621  /* fall-through */
622  default:
623  return 0;
624  }
625 }
626 
634 static inline uint8_t *coap_hdr_data_ptr(const coap_hdr_t *hdr)
635 {
636  return ((uint8_t *)hdr) + sizeof(coap_hdr_t) + coap_hdr_tkl_ext_len(hdr);
637 }
638 
646 static inline unsigned coap_get_total_hdr_len(const coap_pkt_t *pkt)
647 {
648  return sizeof(coap_hdr_t) + coap_hdr_tkl_ext_len(pkt->hdr) +
649  coap_get_token_len(pkt);
650 }
651 
663 static inline unsigned coap_get_response_hdr_len(const coap_pkt_t *pkt)
664 {
665  return coap_get_total_hdr_len(pkt);
666 }
667 
674 static inline void coap_hdr_set_code(coap_hdr_t *hdr, uint8_t code)
675 {
676  hdr->code = code;
677 }
678 
685 static inline void coap_pkt_set_code(coap_pkt_t *pkt, uint8_t code)
686 {
687  coap_hdr_set_code(pkt->hdr, code);
688 }
689 
698 static inline void coap_hdr_set_type(coap_hdr_t *hdr, unsigned type)
699 {
700  /* assert correct range of type */
701  assert(!(type & ~0x3));
702 
703  hdr->ver_t_tkl &= ~0x30;
704  hdr->ver_t_tkl |= type << 4;
705 }
706 
722 static inline size_t coap_hdr_get_token_len(const coap_hdr_t *hdr)
723 {
724  const uint8_t *buf = (const void *)hdr;
725  /* Regarding use unnamed magic numbers 13 and 269:
726  * - If token length is < 13 it fits into TKL field (4 bit)
727  * - If token length is < 269 it fits into 8-bit extended TKL field
728  * - Otherwise token length goes into 16-bit extended TKL field.
729  *
730  * (Not using named constants here, as RFC 8974 also has no names for those
731  * magic numbers.)
732  *
733  * See: https://www.rfc-editor.org/rfc/rfc8974#name-extended-token-length-tkl-f
734  */
735  switch (coap_hdr_tkl_ext_len(hdr)) {
736  case 0:
737  return hdr->ver_t_tkl & 0xf;
738  case 1:
739  return buf[sizeof(coap_hdr_t)] + 13;
740  case 2:
741  return byteorder_bebuftohs(buf + sizeof(coap_hdr_t)) + 269;
742  }
743 
744  return 0;
745 }
746 
762 static inline const void * coap_hdr_get_token(const coap_hdr_t *hdr)
763 {
764  uint8_t *token = (void *)hdr;
765  token += sizeof(*hdr) + coap_hdr_tkl_ext_len(hdr);
766  return token;
767 }
768 
783 static inline size_t coap_hdr_len(const coap_hdr_t *hdr)
784 {
785  return sizeof(*hdr) + coap_hdr_tkl_ext_len(hdr) + coap_hdr_get_token_len(hdr);
786 }
815 uint8_t *coap_find_option(coap_pkt_t *pkt, unsigned opt_num);
816 
829 uint8_t *coap_iterate_option(coap_pkt_t *pkt, unsigned opt_num,
830  uint8_t **opt_pos, int *opt_len);
831 
841 
851 
864 int coap_opt_get_uint(coap_pkt_t *pkt, uint16_t optnum, uint32_t *value);
865 
883 ssize_t coap_opt_get_string(coap_pkt_t *pkt, uint16_t optnum,
884  uint8_t *target, size_t max_len, char separator);
885 
901 static inline ssize_t coap_get_location_path(coap_pkt_t *pkt,
902  uint8_t *target, size_t max_len)
903 {
904  return coap_opt_get_string(pkt, COAP_OPT_LOCATION_PATH,
905  target, max_len, '/');
906 }
907 
923 static inline ssize_t coap_get_location_query(coap_pkt_t *pkt,
924  uint8_t *target, size_t max_len)
925 {
926  return coap_opt_get_string(pkt, COAP_OPT_LOCATION_QUERY,
927  target, max_len, '&');
928 }
929 
944 static inline ssize_t coap_get_uri_path(coap_pkt_t *pkt, uint8_t *target)
945 {
946  return coap_opt_get_string(pkt, COAP_OPT_URI_PATH, target,
948 }
949 
963 static inline ssize_t coap_get_uri_query_string(coap_pkt_t *pkt, char *target,
964  size_t max_len)
965 {
966  return coap_opt_get_string(pkt, COAP_OPT_URI_QUERY,
967  (uint8_t *)target, max_len, '&');
968 }
969 
984 bool coap_find_uri_query(coap_pkt_t *pkt, const char *key,
985  const char **value, size_t *len);
986 
1008 int coap_iterate_uri_query(coap_pkt_t *pkt, void **ctx,
1009  char *key, size_t key_len_max,
1010  char *value, size_t value_len_max);
1011 
1041 ssize_t coap_opt_get_next(const coap_pkt_t *pkt, coap_optpos_t *opt,
1042  uint8_t **value, bool init_opt);
1043 
1060 ssize_t coap_opt_get_opaque(coap_pkt_t *pkt, unsigned opt_num, uint8_t **value);
1075 static inline ssize_t coap_get_proxy_uri(coap_pkt_t *pkt, char **target)
1076 {
1077  return coap_opt_get_opaque(pkt, COAP_OPT_PROXY_URI, (uint8_t **)target);
1078 }
1079 
1097 void coap_block_object_init(coap_block1_t *block, size_t blknum, size_t blksize,
1098  int more);
1099 
1115 bool coap_block_finish(coap_block_slicer_t *slicer, uint16_t option);
1116 
1131 static inline bool coap_block1_finish(coap_block_slicer_t *slicer)
1132 {
1133  return coap_block_finish(slicer, COAP_OPT_BLOCK1);
1134 }
1135 
1150 static inline bool coap_block2_finish(coap_block_slicer_t *slicer)
1151 {
1152  return coap_block_finish(slicer, COAP_OPT_BLOCK2);
1153 }
1154 
1165 
1175 void coap_block_slicer_init(coap_block_slicer_t *slicer, size_t blknum,
1176  size_t blksize);
1177 
1192 size_t coap_blockwise_put_bytes(coap_block_slicer_t *slicer, uint8_t *bufpos,
1193  const void *c, size_t len);
1194 
1208 size_t coap_blockwise_put_char(coap_block_slicer_t *slicer, uint8_t *bufpos, char c);
1209 
1228 int coap_get_block(coap_pkt_t *pkt, coap_block1_t *block, uint16_t option);
1229 
1247 static inline int coap_get_block1(coap_pkt_t *pkt, coap_block1_t *block)
1248 {
1249  return coap_get_block(pkt, block, COAP_OPT_BLOCK1);
1250 }
1251 
1261 static inline int coap_get_block2(coap_pkt_t *pkt, coap_block1_t *block)
1262 {
1263  return coap_get_block(pkt, block, COAP_OPT_BLOCK2);
1264 }
1265 
1278 int coap_get_blockopt(coap_pkt_t *pkt, uint16_t option, uint32_t *blknum, uint8_t *szx);
1279 
1298 
1306 #define coap_szx2size(szx) (1U << ((szx) + 4))
1307 
1315 static inline unsigned coap_size2szx(unsigned len)
1316 {
1317  assert(len >= 16);
1318  return bitarithm_msb(len >> 4);
1319 }
1353  bool more, uint16_t option);
1354 
1373 static inline ssize_t coap_opt_add_block1(coap_pkt_t *pkt,
1374  coap_block_slicer_t *slicer, bool more)
1375 {
1376  return coap_opt_add_block(pkt, slicer, more, COAP_OPT_BLOCK1);
1377 }
1378 
1397 static inline ssize_t coap_opt_add_block2(coap_pkt_t *pkt,
1398  coap_block_slicer_t *slicer, bool more)
1399 {
1400  return coap_opt_add_block(pkt, slicer, more, COAP_OPT_BLOCK2);
1401 }
1416 ssize_t coap_opt_add_uint(coap_pkt_t *pkt, uint16_t optnum, uint32_t value);
1417 
1431 static inline ssize_t coap_opt_add_block1_control(coap_pkt_t *pkt, coap_block1_t *block) {
1432  return coap_opt_add_uint(pkt, COAP_OPT_BLOCK1,
1433  (block->blknum << 4) | block->szx | (block->more ? 0x8 : 0));
1434 }
1435 
1449 static inline ssize_t coap_opt_add_block2_control(coap_pkt_t *pkt, coap_block1_t *block) {
1450  /* block.more must be zero, so no need to 'or' it in */
1451  return coap_opt_add_uint(pkt, COAP_OPT_BLOCK2,
1452  (block->blknum << 4) | block->szx);
1453 }
1454 
1468 static inline ssize_t coap_opt_add_accept(coap_pkt_t *pkt, uint16_t format)
1469 {
1470  return coap_opt_add_uint(pkt, COAP_OPT_ACCEPT, format);
1471 }
1472 
1486 static inline ssize_t coap_opt_add_format(coap_pkt_t *pkt, uint16_t format)
1487 {
1488  return coap_opt_add_uint(pkt, COAP_OPT_CONTENT_FORMAT, format);
1489 }
1490 
1506 ssize_t coap_opt_add_opaque(coap_pkt_t *pkt, uint16_t optnum, const void *val, size_t val_len);
1507 
1525 ssize_t coap_opt_add_uri_query2(coap_pkt_t *pkt, const char *key, size_t key_len,
1526  const char *val, size_t val_len);
1527 
1544 static inline ssize_t coap_opt_add_uri_query(coap_pkt_t *pkt, const char *key,
1545  const char *val)
1546 {
1547  return coap_opt_add_uri_query2(pkt, key, strlen(key), val, val ? strlen(val) : 0);
1548 }
1549 
1564 ssize_t coap_opt_add_proxy_uri(coap_pkt_t *pkt, const char *uri);
1565 
1584 ssize_t coap_opt_add_chars(coap_pkt_t *pkt, uint16_t optnum, const char *chars,
1585  size_t chars_len, char separator);
1586 
1604 static inline ssize_t coap_opt_add_string(coap_pkt_t *pkt, uint16_t optnum,
1605  const char *string, char separator)
1606 {
1607  return coap_opt_add_chars(pkt, optnum, string, strlen(string), separator);
1608 }
1609 
1624 static inline ssize_t coap_opt_add_uri_path(coap_pkt_t *pkt, const char *path)
1625 {
1626  return coap_opt_add_string(pkt, COAP_OPT_URI_PATH, path, '/');
1627 }
1628 
1644 static inline ssize_t coap_opt_add_uri_path_buffer(coap_pkt_t *pkt,
1645  const char *path,
1646  size_t path_len)
1647 {
1648  return coap_opt_add_chars(pkt, COAP_OPT_URI_PATH, path, path_len, '/');
1649 }
1650 
1663 ssize_t coap_opt_finish(coap_pkt_t *pkt, uint16_t flags);
1664 
1682 ssize_t coap_opt_remove(coap_pkt_t *pkt, uint16_t optnum);
1710 size_t coap_opt_put_block(uint8_t *buf, uint16_t lastonum, coap_block_slicer_t *slicer,
1711  bool more, uint16_t option);
1712 
1728 static inline size_t coap_opt_put_block1(uint8_t *buf, uint16_t lastonum,
1729  coap_block_slicer_t *slicer, bool more)
1730 {
1731  return coap_opt_put_block(buf, lastonum, slicer, more, COAP_OPT_BLOCK1);
1732 }
1733 
1749 static inline size_t coap_opt_put_block2(uint8_t *buf, uint16_t lastonum,
1750  coap_block_slicer_t *slicer, bool more)
1751 {
1752  return coap_opt_put_block(buf, lastonum, slicer, more, COAP_OPT_BLOCK2);
1753 }
1754 
1766 size_t coap_opt_put_uint(uint8_t *buf, uint16_t lastonum, uint16_t onum,
1767  uint32_t value);
1768 
1778 static inline size_t coap_opt_put_block1_control(uint8_t *buf, uint16_t lastonum,
1779  coap_block1_t *block)
1780 {
1781  return coap_opt_put_uint(buf, lastonum, COAP_OPT_BLOCK1,
1782  (block->blknum << 4) | block->szx | (block->more ? 0x8 : 0));
1783 }
1784 
1796 static inline size_t coap_opt_put_block2_control(uint8_t *buf, uint16_t lastonum,
1797  coap_block1_t *block)
1798 {
1799  /* block.more must be zero, so no need to 'or' it in */
1800  return coap_opt_put_uint(buf, lastonum, COAP_OPT_BLOCK2,
1801  (block->blknum << 4) | block->szx);
1802 }
1803 
1813 static inline size_t coap_opt_put_observe(uint8_t *buf, uint16_t lastonum,
1814  uint32_t obs)
1815 {
1816  obs &= COAP_OBS_MAX_VALUE_MASK; /* trim obs down to 24 bit */
1817  return coap_opt_put_uint(buf, lastonum, COAP_OPT_OBSERVE, obs);
1818 }
1819 
1833 size_t coap_opt_put_string_with_len(uint8_t *buf, uint16_t lastonum, uint16_t optnum,
1834  const char *string, size_t len, char separator);
1847 static inline size_t coap_opt_put_string(uint8_t *buf, uint16_t lastonum,
1848  uint16_t optnum,
1849  const char *string, char separator)
1850 {
1851  return coap_opt_put_string_with_len(buf, lastonum, optnum,
1852  string, strlen(string), separator);
1853 }
1854 
1865 static inline size_t coap_opt_put_location_path(uint8_t *buf,
1866  uint16_t lastonum,
1867  const char *location)
1868 {
1869  return coap_opt_put_string(buf, lastonum, COAP_OPT_LOCATION_PATH,
1870  location, '/');
1871 }
1872 
1883 static inline size_t coap_opt_put_location_query(uint8_t *buf,
1884  uint16_t lastonum,
1885  const char *location)
1886 {
1887  return coap_opt_put_string(buf, lastonum, COAP_OPT_LOCATION_QUERY,
1888  location, '&');
1889 }
1890 
1901 static inline size_t coap_opt_put_uri_path(uint8_t *buf, uint16_t lastonum,
1902  const char *uri)
1903 {
1904  return coap_opt_put_string(buf, lastonum, COAP_OPT_URI_PATH, uri, '/');
1905 }
1906 
1917 static inline size_t coap_opt_put_uri_query(uint8_t *buf, uint16_t lastonum,
1918  const char *uri)
1919 {
1920  return coap_opt_put_string(buf, lastonum, COAP_OPT_URI_QUERY, uri, '&');
1921 }
1922 
1941 size_t coap_opt_put_uri_pathquery(uint8_t *buf, uint16_t *lastonum, const char *uri);
1942 
1953 static inline size_t coap_opt_put_proxy_uri(uint8_t *buf, uint16_t lastonum,
1954  const char *uri)
1955 {
1956  return coap_opt_put_string(buf, lastonum, COAP_OPT_PROXY_URI, uri, '\0');
1957 }
1958 
1976 size_t coap_put_block1_ok(uint8_t *pkt_pos, coap_block1_t *block1, uint16_t lastonum);
1977 
1994 size_t coap_put_option(uint8_t *buf, uint16_t lastonum, uint16_t onum, const void *odata, size_t olen);
1995 
2008 static inline size_t coap_put_option_block1(uint8_t *buf, uint16_t lastonum,
2009  unsigned blknum, unsigned szx, int more)
2010 {
2011  return coap_opt_put_uint(buf, lastonum, COAP_OPT_BLOCK1,
2012  (blknum << 4) | szx | (more ? 0x8 : 0));
2013 }
2014 
2025 static inline size_t coap_put_option_ct(uint8_t *buf, uint16_t lastonum,
2026  uint16_t content_type)
2027 {
2028  return coap_opt_put_uint(buf, lastonum, COAP_OPT_CONTENT_FORMAT, content_type);
2029 }
2058 ssize_t coap_block2_build_reply(coap_pkt_t *pkt, unsigned code,
2059  uint8_t *rbuf, unsigned rlen, unsigned payload_len,
2060  coap_block_slicer_t *slicer);
2061 
2081 ssize_t coap_build_hdr(coap_hdr_t *hdr, unsigned type, const void *token,
2082  size_t token_len, unsigned code, uint16_t id);
2083 
2143 ssize_t coap_build_reply(coap_pkt_t *pkt, unsigned code,
2144  uint8_t *rbuf, unsigned rlen, unsigned max_data_len);
2145 
2161 
2176 ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_len,
2177  coap_request_ctx_t *ctx);
2178 
2195 ssize_t coap_tree_handler(coap_pkt_t *pkt, uint8_t *resp_buf,
2196  unsigned resp_buf_len, coap_request_ctx_t *ctx,
2197  const coap_resource_t *resources,
2198  size_t resources_numof);
2199 
2217 ssize_t coap_subtree_handler(coap_pkt_t *pkt, uint8_t *resp_buf,
2218  size_t resp_buf_len, coap_request_ctx_t *context);
2219 
2227 static inline coap_method_flags_t coap_method2flag(unsigned code)
2228 {
2229  return (1 << (code - 1));
2230 }
2231 
2246 int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len);
2247 
2262 void coap_pkt_init(coap_pkt_t *pkt, uint8_t *buf, size_t len, size_t header_len);
2263 
2277 static inline void coap_payload_advance_bytes(coap_pkt_t *pkt, size_t len)
2278 {
2279  pkt->payload += len;
2280  pkt->payload_len -= len;
2281 }
2282 
2304 ssize_t coap_payload_put_bytes(coap_pkt_t *pkt, const void *data, size_t len);
2305 
2319 ssize_t coap_payload_put_char(coap_pkt_t *pkt, char c);
2320 
2346 ssize_t coap_build_reply_header(coap_pkt_t *pkt, unsigned code,
2347  void *buf, size_t len, uint16_t ct,
2348  void **payload, size_t *payload_len_max);
2349 
2374  unsigned code,
2375  uint8_t *buf, size_t len,
2376  uint16_t ct,
2377  const void *payload, size_t payload_len);
2378 
2384  uint8_t *buf, size_t len,
2385  coap_request_ctx_t *context);
2391 #ifndef CONFIG_NANOCOAP_SERVER_WELL_KNOWN_CORE
2392 #define CONFIG_NANOCOAP_SERVER_WELL_KNOWN_CORE !IS_USED(MODULE_GCOAP)
2393 #endif
2394 
2410 int coap_match_path(const coap_resource_t *resource, const uint8_t *uri);
2411 
2412 #if defined(MODULE_GCOAP) || defined(DOXYGEN)
2425 static inline bool coap_has_observe(coap_pkt_t *pkt)
2426 {
2427  return pkt->observe_value != UINT32_MAX;
2428 }
2429 
2435 static inline void coap_clear_observe(coap_pkt_t *pkt)
2436 {
2437  pkt->observe_value = UINT32_MAX;
2438 }
2439 
2447 static inline uint32_t coap_get_observe(coap_pkt_t *pkt)
2448 {
2449  return pkt->observe_value;
2450 }
2452 #endif
2453 
2457 #define COAP_WELL_KNOWN_CORE_DEFAULT_HANDLER \
2458  { \
2459  .path = "/.well-known/core", \
2460  .methods = COAP_GET, \
2461  .handler = coap_well_known_core_default_handler \
2462  }
2463 
2464 #ifdef __cplusplus
2465 }
2466 #endif
POSIX.1-2008 compliant version of the assert macro.
#define assert(cond)
abort the program if assertion is false
Definition: assert.h:143
Helper functions for bit arithmetic.
static unsigned bitarithm_msb(unsigned v)
Returns the number of the highest '1' bit in a value.
Definition: bitarithm.h:149
bitfields operations on bitfields of arbitrary length
Functions to work with different byte orders.
static uint16_t ntohs(uint16_t v)
Convert from network byte order to host byte order, 16 bit.
Definition: byteorder.h:532
static uint16_t byteorder_bebuftohs(const uint8_t *buf)
Read a big endian encoded unsigned integer from a buffer into host byte order encoded variable,...
Definition: byteorder.h:547
Various helper macros.
#define COAP_OBS_MAX_VALUE_MASK
observe value is 24 bits
Definition: coap.h:518
coap_method_t
CoAP method codes used in request.
Definition: coap.h:167
#define CONFIG_NANOCOAP_NOPTS_MAX
Maximum number of Options in a message.
Definition: nanocoap.h:132
#define CONFIG_NANOCOAP_URI_MAX
Maximum length of a resource path string read from or written to a message.
Definition: nanocoap.h:140
static size_t coap_hdr_get_token_len(const coap_hdr_t *hdr)
Get the token length of a CoAP over UDP (DTLS) packet.
Definition: nanocoap.h:722
uint32_t coap_request_ctx_get_tl_type(const coap_request_ctx_t *ctx)
Get transport the packet was received over.
uint8_t * coap_iterate_option(coap_pkt_t *pkt, unsigned opt_num, uint8_t **opt_pos, int *opt_len)
Get pointer to an option field, can be called in a loop if there are multiple options with the same n...
static ssize_t coap_opt_add_uri_query(coap_pkt_t *pkt, const char *key, const char *val)
Adds a single Uri-Query option in the form 'key=value' into pkt.
Definition: nanocoap.h:1544
static void coap_pkt_set_code(coap_pkt_t *pkt, uint8_t code)
Write the given raw message code to given CoAP pkt.
Definition: nanocoap.h:685
static size_t coap_opt_put_uri_query(uint8_t *buf, uint16_t lastonum, const char *uri)
Convenience function for inserting URI_QUERY option into buffer.
Definition: nanocoap.h:1917
size_t coap_opt_put_block(uint8_t *buf, uint16_t lastonum, coap_block_slicer_t *slicer, bool more, uint16_t option)
Insert block option into buffer.
static size_t coap_opt_put_block2_control(uint8_t *buf, uint16_t lastonum, coap_block1_t *block)
Insert block2 option into buffer in control usage.
Definition: nanocoap.h:1796
static ssize_t coap_opt_add_block2(coap_pkt_t *pkt, coap_block_slicer_t *slicer, bool more)
Add block2 option in descriptive use from a slicer object.
Definition: nanocoap.h:1397
static unsigned coap_get_code_raw(const coap_pkt_t *pkt)
Get a message's raw code (class + detail)
Definition: nanocoap.h:501
static size_t coap_hdr_len(const coap_hdr_t *hdr)
Get the header length of a CoAP packet.
Definition: nanocoap.h:783
void coap_pkt_init(coap_pkt_t *pkt, uint8_t *buf, size_t len, size_t header_len)
Initialize a packet struct, to build a message buffer.
int coap_match_path(const coap_resource_t *resource, const uint8_t *uri)
Checks if a CoAP resource path matches a given URI.
static size_t coap_opt_put_block1(uint8_t *buf, uint16_t lastonum, coap_block_slicer_t *slicer, bool more)
Insert block1 option into buffer.
Definition: nanocoap.h:1728
static ssize_t coap_opt_add_format(coap_pkt_t *pkt, uint16_t format)
Append a Content-Format option to the pkt buffer.
Definition: nanocoap.h:1486
static uint8_t coap_code(unsigned cls, unsigned detail)
Encode given code class and code detail to raw code.
Definition: nanocoap.h:453
bool coap_has_unprocessed_critical_options(const coap_pkt_t *pkt)
Check whether any of the packet's options that are critical.
static ssize_t coap_opt_add_uri_path(coap_pkt_t *pkt, const char *path)
Adds one or multiple Uri-Path options in the form '/path' into pkt.
Definition: nanocoap.h:1624
static ssize_t coap_get_uri_query_string(coap_pkt_t *pkt, char *target, size_t max_len)
Convenience function for getting the packet's URI_QUERY option.
Definition: nanocoap.h:963
ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_len, coap_request_ctx_t *ctx)
Handle incoming CoAP request.
static unsigned coap_get_id(const coap_pkt_t *pkt)
Get the message ID of the given CoAP packet.
Definition: nanocoap.h:525
static ssize_t coap_get_location_query(coap_pkt_t *pkt, uint8_t *target, size_t max_len)
Convenience function for getting the packet's LOCATION_QUERY option.
Definition: nanocoap.h:923
static size_t coap_opt_put_uri_path(uint8_t *buf, uint16_t lastonum, const char *uri)
Convenience function for inserting URI_PATH option into buffer.
Definition: nanocoap.h:1901
static ssize_t coap_opt_add_accept(coap_pkt_t *pkt, uint16_t format)
Append an Accept option to the pkt buffer.
Definition: nanocoap.h:1468
ssize_t coap_opt_get_string(coap_pkt_t *pkt, uint16_t optnum, uint8_t *target, size_t max_len, char separator)
Read a full option as null terminated string into the target buffer.
size_t coap_opt_put_uint(uint8_t *buf, uint16_t lastonum, uint16_t onum, uint32_t value)
Encode the given uint option into buffer.
void coap_request_ctx_init(coap_request_ctx_t *ctx, sock_udp_ep_t *remote)
Initialize CoAP request context.
static void coap_hdr_set_code(coap_hdr_t *hdr, uint8_t code)
Write the given raw message code to given CoAP header.
Definition: nanocoap.h:674
ssize_t coap_payload_put_bytes(coap_pkt_t *pkt, const void *data, size_t len)
Add payload data to the CoAP request.
uint8_t * coap_find_option(coap_pkt_t *pkt, unsigned opt_num)
Get pointer to an option field by type.
int coap_opt_get_uint(coap_pkt_t *pkt, uint16_t optnum, uint32_t *value)
Get a uint32 option value.
unsigned coap_get_accept(coap_pkt_t *pkt)
Get the Accept option value from a packet if present.
static size_t coap_opt_put_string(uint8_t *buf, uint16_t lastonum, uint16_t optnum, const char *string, char separator)
Encode the given string as multi-part option into buffer.
Definition: nanocoap.h:1847
uint16_t coap_method_flags_t
Method flag type.
Definition: nanocoap.h:292
int coap_get_block(coap_pkt_t *pkt, coap_block1_t *block, uint16_t option)
Block option getter.
static unsigned coap_get_ver(const coap_pkt_t *pkt)
Get the CoAP version number.
Definition: nanocoap.h:593
ssize_t coap_opt_get_next(const coap_pkt_t *pkt, coap_optpos_t *opt, uint8_t **value, bool init_opt)
Iterate over a packet's options.
static size_t coap_opt_put_block2(uint8_t *buf, uint16_t lastonum, coap_block_slicer_t *slicer, bool more)
Insert block2 option into buffer.
Definition: nanocoap.h:1749
static size_t coap_opt_put_observe(uint8_t *buf, uint16_t lastonum, uint32_t obs)
Insert an CoAP Observe Option into the buffer.
Definition: nanocoap.h:1813
static bool coap_block2_finish(coap_block_slicer_t *slicer)
Finish a block2 response.
Definition: nanocoap.h:1150
size_t coap_blockwise_put_bytes(coap_block_slicer_t *slicer, uint8_t *bufpos, const void *c, size_t len)
Add a byte array to a block2 reply.
static uint8_t coap_hdr_tkl_ext_len(const coap_hdr_t *hdr)
Get the size of the extended Token length field (RFC 8974)
Definition: nanocoap.h:608
static coap_method_t coap_get_method(const coap_pkt_t *pkt)
Get a request's method type.
Definition: nanocoap.h:513
static unsigned coap_get_total_hdr_len(const coap_pkt_t *pkt)
Get the total header length (4-byte header + token length)
Definition: nanocoap.h:646
ssize_t coap_subtree_handler(coap_pkt_t *pkt, uint8_t *resp_buf, size_t resp_buf_len, coap_request_ctx_t *context)
Generic coap subtree handler.
static unsigned coap_get_code_class(const coap_pkt_t *pkt)
Get a message's code class (3 most significant bits of code)
Definition: nanocoap.h:465
static int coap_get_block2(coap_pkt_t *pkt, coap_block1_t *block)
Block2 option getter.
Definition: nanocoap.h:1261
ssize_t coap_build_empty_ack(coap_pkt_t *pkt, coap_hdr_t *ack)
Build empty reply to CoAP request.
ssize_t coap_block2_build_reply(coap_pkt_t *pkt, unsigned code, uint8_t *rbuf, unsigned rlen, unsigned payload_len, coap_block_slicer_t *slicer)
Build reply to CoAP block2 request.
void coap_block_slicer_init(coap_block_slicer_t *slicer, size_t blknum, size_t blksize)
Initialize a block slicer struct from content information.
static ssize_t coap_get_location_path(coap_pkt_t *pkt, uint8_t *target, size_t max_len)
Convenience function for getting the packet's LOCATION_PATH option.
Definition: nanocoap.h:901
size_t coap_opt_put_string_with_len(uint8_t *buf, uint16_t lastonum, uint16_t optnum, const char *string, size_t len, char separator)
Encode the given string as multi-part option into buffer.
static ssize_t coap_opt_add_string(coap_pkt_t *pkt, uint16_t optnum, const char *string, char separator)
Encode the given string as option(s) into pkt.
Definition: nanocoap.h:1604
bool coap_block_finish(coap_block_slicer_t *slicer, uint16_t option)
Finish a block request (block1 or block2)
static unsigned coap_get_code_detail(const coap_pkt_t *pkt)
Get a message's code detail (5 least significant bits of code)
Definition: nanocoap.h:477
static int coap_get_block1(coap_pkt_t *pkt, coap_block1_t *block)
Block1 option getter.
Definition: nanocoap.h:1247
void coap_block2_init(coap_pkt_t *pkt, coap_block_slicer_t *slicer)
Initialize a block2 slicer struct for writing the payload.
static uint8_t * coap_hdr_data_ptr(const coap_hdr_t *hdr)
Get the start of data after the header.
Definition: nanocoap.h:634
ssize_t(* coap_handler_t)(coap_pkt_t *pkt, uint8_t *buf, size_t len, coap_request_ctx_t *context)
Resource handler type.
Definition: nanocoap.h:258
ssize_t coap_payload_put_char(coap_pkt_t *pkt, char c)
Add a single character to the payload data of the CoAP request.
ssize_t coap_well_known_core_default_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, coap_request_ctx_t *context)
Reference to the default .well-known/core handler defined by the application.
static size_t coap_opt_put_proxy_uri(uint8_t *buf, uint16_t lastonum, const char *uri)
Convenience function for inserting PROXY_URI option into buffer.
Definition: nanocoap.h:1953
static void coap_hdr_set_type(coap_hdr_t *hdr, unsigned type)
Set the message type for the given CoAP header.
Definition: nanocoap.h:698
static void coap_payload_advance_bytes(coap_pkt_t *pkt, size_t len)
Advance the payload pointer.
Definition: nanocoap.h:2277
bool coap_find_uri_query(coap_pkt_t *pkt, const char *key, const char **value, size_t *len)
Find a URI query option of the packet.
static uint32_t coap_get_observe(coap_pkt_t *pkt)
Get the value of the observe option from the given packet.
Definition: nanocoap.h:2447
static const void * coap_hdr_get_token(const coap_hdr_t *hdr)
Get the Token of a CoAP over UDP (DTLS) packet.
Definition: nanocoap.h:762
static size_t coap_put_option_block1(uint8_t *buf, uint16_t lastonum, unsigned blknum, unsigned szx, int more)
Insert block1 option into buffer.
Definition: nanocoap.h:2008
static ssize_t coap_opt_add_block2_control(coap_pkt_t *pkt, coap_block1_t *block)
Encode the given block2 option in control use.
Definition: nanocoap.h:1449
static unsigned coap_get_type(const coap_pkt_t *pkt)
Get the message type.
Definition: nanocoap.h:581
static unsigned coap_get_code_decimal(const coap_pkt_t *pkt)
Get a message's code in decimal format ((class * 100) + detail)
Definition: nanocoap.h:489
static unsigned coap_get_response_hdr_len(const coap_pkt_t *pkt)
Get the header length a response to the given packet will have.
Definition: nanocoap.h:663
ssize_t coap_opt_get_opaque(coap_pkt_t *pkt, unsigned opt_num, uint8_t **value)
Retrieve the value for an option as an opaque array of bytes.
size_t coap_put_option(uint8_t *buf, uint16_t lastonum, uint16_t onum, const void *odata, size_t olen)
Insert a CoAP option into buffer.
int coap_iterate_uri_query(coap_pkt_t *pkt, void **ctx, char *key, size_t key_len_max, char *value, size_t value_len_max)
Iterate over a packet's URI Query options.
ssize_t coap_opt_add_opaque(coap_pkt_t *pkt, uint16_t optnum, const void *val, size_t val_len)
Encode the given buffer as an opaque data option into pkt.
static ssize_t coap_opt_add_uri_path_buffer(coap_pkt_t *pkt, const char *path, size_t path_len)
Adds one or multiple Uri-Path options in the form '/path' into pkt.
Definition: nanocoap.h:1644
const char * coap_request_ctx_get_path(const coap_request_ctx_t *ctx)
Get resource path associated with a CoAP request.
static size_t coap_opt_put_location_query(uint8_t *buf, uint16_t lastonum, const char *location)
Convenience function for inserting LOCATION_QUERY option into buffer.
Definition: nanocoap.h:1883
int coap_get_blockopt(coap_pkt_t *pkt, uint16_t option, uint32_t *blknum, uint8_t *szx)
Generic block option getter.
size_t coap_blockwise_put_char(coap_block_slicer_t *slicer, uint8_t *bufpos, char c)
Add a single character to a block2 reply.
static size_t coap_opt_put_location_path(uint8_t *buf, uint16_t lastonum, const char *location)
Convenience function for inserting LOCATION_PATH option into buffer.
Definition: nanocoap.h:1865
static bool coap_block1_finish(coap_block_slicer_t *slicer)
Finish a block1 request.
Definition: nanocoap.h:1131
const sock_udp_ep_t * coap_request_ctx_get_local_udp(const coap_request_ctx_t *ctx)
Get the local endpoint on which the request has been received.
ssize_t coap_build_reply_header(coap_pkt_t *pkt, unsigned code, void *buf, size_t len, uint16_t ct, void **payload, size_t *payload_len_max)
Create CoAP reply header (convenience function)
static size_t coap_put_option_ct(uint8_t *buf, uint16_t lastonum, uint16_t content_type)
Insert content type option into buffer.
Definition: nanocoap.h:2025
ssize_t coap_opt_add_proxy_uri(coap_pkt_t *pkt, const char *uri)
Adds a single Proxy-URI option into pkt.
int(* coap_blockwise_cb_t)(void *arg, size_t offset, uint8_t *buf, size_t len, int more)
Coap blockwise request callback descriptor.
Definition: nanocoap.h:273
ssize_t coap_build_reply(coap_pkt_t *pkt, unsigned code, uint8_t *rbuf, unsigned rlen, unsigned max_data_len)
Build reply to CoAP request.
static unsigned coap_size2szx(unsigned len)
Helper to encode byte size into next equal or smaller SZX value.
Definition: nanocoap.h:1315
int(* coap_request_cb_t)(void *arg, coap_pkt_t *pkt)
Coap request callback descriptor.
Definition: nanocoap.h:285
static size_t coap_opt_put_block1_control(uint8_t *buf, uint16_t lastonum, coap_block1_t *block)
Insert block1 option into buffer in control usage.
Definition: nanocoap.h:1778
ssize_t coap_reply_simple(coap_pkt_t *pkt, unsigned code, uint8_t *buf, size_t len, uint16_t ct, const void *payload, size_t payload_len)
Create CoAP reply (convenience function)
void * coap_request_ctx_get_context(const coap_request_ctx_t *ctx)
Get resource context associated with a CoAP request.
ssize_t coap_opt_add_block(coap_pkt_t *pkt, coap_block_slicer_t *slicer, bool more, uint16_t option)
Add block option in descriptive use from a slicer object.
const sock_udp_ep_t * coap_request_ctx_get_remote_udp(const coap_request_ctx_t *ctx)
Get the remote endpoint from which the request was received.
int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len)
Parse a CoAP PDU.
void coap_block_object_init(coap_block1_t *block, size_t blknum, size_t blksize, int more)
Initialize a block struct from content information.
ssize_t coap_opt_add_chars(coap_pkt_t *pkt, uint16_t optnum, const char *chars, size_t chars_len, char separator)
Encode the given array of characters as option(s) into pkt.
ssize_t coap_opt_remove(coap_pkt_t *pkt, uint16_t optnum)
Removes an option previously added with function in the coap_opt_add_...() group.
unsigned coap_get_content_type(coap_pkt_t *pkt)
Get content type from packet.
static ssize_t coap_get_proxy_uri(coap_pkt_t *pkt, char **target)
Convenience function for getting the packet's Proxy-Uri option.
Definition: nanocoap.h:1075
static ssize_t coap_get_uri_path(coap_pkt_t *pkt, uint8_t *target)
Convenience function for getting the packet's URI_PATH.
Definition: nanocoap.h:944
ssize_t coap_opt_add_uint(coap_pkt_t *pkt, uint16_t optnum, uint32_t value)
Encode the given uint option into pkt.
static unsigned coap_get_total_len(const coap_pkt_t *pkt)
Get the total length of a CoAP packet in the packet buffer.
Definition: nanocoap.h:566
static bool coap_has_observe(coap_pkt_t *pkt)
Identifies a packet containing an observe option.
Definition: nanocoap.h:2425
ssize_t coap_build_hdr(coap_hdr_t *hdr, unsigned type, const void *token, size_t token_len, unsigned code, uint16_t id)
Builds a CoAP header.
size_t coap_put_block1_ok(uint8_t *pkt_pos, coap_block1_t *block1, uint16_t lastonum)
Insert block1 option into buffer (from coap_block1_t)
static ssize_t coap_opt_add_block1(coap_pkt_t *pkt, coap_block_slicer_t *slicer, bool more)
Add block1 option in descriptive use from a slicer object.
Definition: nanocoap.h:1373
static coap_method_flags_t coap_method2flag(unsigned code)
Convert message code (request method) into a corresponding bit field.
Definition: nanocoap.h:2227
size_t coap_opt_put_uri_pathquery(uint8_t *buf, uint16_t *lastonum, const char *uri)
Convenience function for inserting URI_PATH and URI_QUERY into buffer This function will automaticall...
static ssize_t coap_opt_add_block1_control(coap_pkt_t *pkt, coap_block1_t *block)
Encode the given block1 option in control use.
Definition: nanocoap.h:1431
ssize_t coap_tree_handler(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_len, coap_request_ctx_t *ctx, const coap_resource_t *resources, size_t resources_numof)
Pass a coap request to a matching handler.
static unsigned coap_get_token_len(const coap_pkt_t *pkt)
Get a message's token length [in byte].
Definition: nanocoap.h:540
static void * coap_get_token(const coap_pkt_t *pkt)
Get pointer to a message's token.
Definition: nanocoap.h:552
static void coap_clear_observe(coap_pkt_t *pkt)
Clears the observe option value from a packet.
Definition: nanocoap.h:2435
ssize_t coap_opt_finish(coap_pkt_t *pkt, uint16_t flags)
Finalizes options as required and prepares for payload.
ssize_t coap_opt_add_uri_query2(coap_pkt_t *pkt, const char *key, size_t key_len, const char *val, size_t val_len)
Adds a single Uri-Query option in the form 'key=value' into pkt.
iolist scatter / gather IO
Common macros and compiler attributes/pragmas configuration.
#define IS_USED(module)
Checks whether a module is being used or not.
Definition: modules.h:67
Generic CoAP values as defined by RFC7252.
UDP sock definitions.
CoAP resource request handler context.
Definition: nanocoap.h:324
sock_udp_ep_t * local
local endpoint of the request
Definition: nanocoap.h:328
const coap_resource_t * resource
resource of the request
Definition: nanocoap.h:325
sock_udp_ep_t * remote
remote endpoint of the request
Definition: nanocoap.h:326
uint32_t tl_type
transport the packet was received over
Definition: nanocoap.h:337
Common IP-based transport layer end point.
Definition: sock.h:211
Block1 helper struct.
Definition: nanocoap.h:397
int8_t more
-1 for no option, 0 for last block, 1 for more blocks coming
Definition: nanocoap.h:401
uint32_t blknum
block number
Definition: nanocoap.h:399
size_t offset
offset of received data
Definition: nanocoap.h:398
uint8_t szx
szx value
Definition: nanocoap.h:400
Blockwise transfer helper struct.
Definition: nanocoap.h:408
uint8_t * opt
Pointer to the placed option
Definition: nanocoap.h:412
size_t end
End offset of the current block
Definition: nanocoap.h:410
size_t start
Start offset of the current block
Definition: nanocoap.h:409
size_t cur
Offset of the generated content
Definition: nanocoap.h:411
Raw CoAP PDU header structure.
Definition: nanocoap.h:187
uint8_t ver_t_tkl
version, token, token length
Definition: nanocoap.h:188
uint8_t code
CoAP code (e.g.m 205)
Definition: nanocoap.h:189
uint16_t id
Req/resp ID
Definition: nanocoap.h:190
CoAP option array entry.
Definition: nanocoap.h:196
uint16_t offset
offset in packet
Definition: nanocoap.h:198
uint16_t opt_num
full CoAP option number
Definition: nanocoap.h:197
CoAP PDU parsing context structure.
Definition: nanocoap.h:218
uint8_t * payload
pointer to end of the header
Definition: nanocoap.h:220
uint16_t payload_len
length of payload
Definition: nanocoap.h:222
coap_hdr_t * hdr
pointer to raw packet
Definition: nanocoap.h:219
uint16_t options_len
length of options array
Definition: nanocoap.h:223
BITFIELD(opt_crit, CONFIG_NANOCOAP_NOPTS_MAX)
unhandled critical option
iolist_t * snips
payload snips (optional)
Definition: nanocoap.h:221
Type for CoAP resource subtrees.
Definition: nanocoap.h:307
const size_t resources_numof
number of entries in array
Definition: nanocoap.h:309
const coap_resource_t * resources
ptr to resource array
Definition: nanocoap.h:308
Type for CoAP resource entry.
Definition: nanocoap.h:297
const char * path
URI path of resource
Definition: nanocoap.h:298
coap_method_flags_t methods
OR'ed methods this resource allows.
Definition: nanocoap.h:299
coap_handler_t handler
ptr to resource handler
Definition: nanocoap.h:300
void * context
ptr to user defined context data
Definition: nanocoap.h:301
iolist structure definition
Definition: iolist.h:35
Cross File Arrays.