Loading...
Searching...
No Matches
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
75
76#include <assert.h>
77#include <stdint.h>
78#include <stdbool.h>
79#include <stddef.h>
80#include <string.h>
81#include <unistd.h>
82
83#include "bitfield.h"
84#include "byteorder.h"
85#include "iolist.h"
86#include "modules.h"
87#include "net/coap.h"
88#include "net/sock/udp.h"
89
90#if defined(MODULE_NANOCOAP_RESOURCES)
91# include "xfa.h"
92#endif
93
94#ifdef __cplusplus
95extern "C" {
96#endif
97
103#define COAP_GET (0x01)
104#define COAP_POST (0x02)
105#define COAP_PUT (0x04)
106#define COAP_DELETE (0x08)
107#define COAP_FETCH (0x10)
108#define COAP_PATCH (0x20)
109#define COAP_IPATCH (0x40)
110#define COAP_IGNORE (0xFF)
112#define COAP_MATCH_SUBTREE (0x8000)
115
119#define COAP_FORMAT_NONE (UINT16_MAX)
120
128#ifndef CONFIG_NANOCOAP_NOPTS_MAX
129# define CONFIG_NANOCOAP_NOPTS_MAX (16)
130#endif
131
136#ifndef CONFIG_NANOCOAP_URI_MAX
137# define CONFIG_NANOCOAP_URI_MAX (64)
138#endif
139
143#ifndef CONFIG_NANOCOAP_BLOCK_SIZE_MAX
144# define CONFIG_NANOCOAP_BLOCK_SIZE_MAX COAP_BLOCKSIZE_64
145#endif
146
150#ifndef CONFIG_NANOCOAP_BLOCKSIZE_DEFAULT
151# define CONFIG_NANOCOAP_BLOCKSIZE_DEFAULT COAP_BLOCKSIZE_64
152#endif
153
155#ifndef CONFIG_NANOCOAP_QS_MAX
156# define CONFIG_NANOCOAP_QS_MAX (64)
157#endif
159
165#ifndef CONFIG_NANOCOAP_BLOCK_HEADER_MAX
166# define CONFIG_NANOCOAP_BLOCK_HEADER_MAX (80)
167#endif
168
176#define COAP_OPT_FINISH_NONE (0x0000)
178#define COAP_OPT_FINISH_PAYLOAD (0x0001)
180
184typedef struct __attribute__((packed)) {
185 uint8_t ver_t_tkl;
186 uint8_t code;
187 uint16_t id;
189
193typedef struct {
194 uint16_t opt_num;
195 uint16_t offset;
197
216typedef struct {
222 uint8_t *buf;
223 uint8_t *payload;
225 uint16_t payload_len;
226 uint16_t options_len;
229#ifdef MODULE_GCOAP
230 uint32_t observe_value;
231#endif
232} coap_pkt_t;
233
238
261typedef ssize_t (*coap_handler_t)(coap_pkt_t *pkt, uint8_t *buf, size_t len,
262 coap_request_ctx_t *context);
263
276typedef int (*coap_blockwise_cb_t)(void *arg, size_t offset, uint8_t *buf, size_t len, int more);
277
288typedef int (*coap_request_cb_t)(void *arg, coap_pkt_t *pkt);
289
295typedef uint16_t coap_method_flags_t;
296
306
310typedef const struct {
312 const size_t resources_numof;
314
322
329 union {
332 };
333#if defined(MODULE_SOCK_AUX_LOCAL) || DOXYGEN
334 union {
337 };
338#endif
339#if defined(MODULE_GCOAP) || DOXYGEN
346 uint32_t tl_type;
347#endif
348};
349
358
367
377
387
397
422typedef struct {
423 uint8_t *buf;
424 uint16_t pos;
425 uint16_t size;
426 uint16_t last_opt_num;
428
438 size_t offset;
439 uint32_t blknum;
440 uint8_t szx;
441 bool more;
442};
443
448
453
457typedef struct {
458 size_t start;
459 size_t end;
460 size_t cur;
461 uint8_t *opt_value;
463
464#if defined(MODULE_NANOCOAP_RESOURCES) || DOXYGEN
470#define NANOCOAP_RESOURCE(name) \
471 XFA_CONST(coap_resource_t, coap_resources_xfa, 0) CONCAT(coap_resource_, name) =
472#else
478extern const coap_resource_t coap_resources[];
479
485extern const unsigned coap_resources_numof;
486#endif
487
501{
502 /* currently only UDP as transport supported */
503 return (coap_udp_hdr_t *)pkt->buf;
504}
505
509static inline const coap_udp_hdr_t *coap_get_udp_hdr_const(const coap_pkt_t *pkt)
510{
511 /* currently only UDP as transport supported */
512 return (const coap_udp_hdr_t *)pkt->buf;
513}
514
523static inline uint8_t coap_code(unsigned cls, unsigned detail)
524{
525 return (cls << 5) | detail;
526}
527
535static inline unsigned coap_get_code_raw(const coap_pkt_t *pkt)
536{
537 return coap_get_udp_hdr_const(pkt)->code;
538}
539
547static inline unsigned coap_get_code_class(const coap_pkt_t *pkt)
548{
549 return coap_get_code_raw(pkt) >> 5;
550}
551
559static inline unsigned coap_get_code_detail(const coap_pkt_t *pkt)
560{
561 return coap_get_code_raw(pkt) & 0x1f;
562}
563
571static inline unsigned coap_get_code_decimal(const coap_pkt_t *pkt)
572{
573 return (coap_get_code_class(pkt) * 100) + coap_get_code_detail(pkt);
574}
575
583static inline coap_method_t coap_get_method(const coap_pkt_t *pkt)
584{
585 return coap_get_code_raw(pkt);
586}
587
595static inline unsigned coap_get_id(const coap_pkt_t *pkt)
596{
597 return ntohs(coap_get_udp_hdr_const(pkt)->id);
598}
599
606static inline void coap_set_id(coap_pkt_t *pkt, uint16_t id)
607{
608 coap_get_udp_hdr(pkt)->id = htons(id);
609}
610
618static inline unsigned coap_get_token_len(const coap_pkt_t *pkt)
619{
620 const coap_udp_hdr_t *udp = coap_get_udp_hdr_const(pkt);
621 /*
622 * Layout of first byte of header (cut out of Figure 7 of RFC7252)
623 * see https://datatracker.ietf.org/doc/html/rfc7252#section-3
624 * 0 1 2 3 4 5 6 7
625 * +-+-+-+-+-+-+-+-+
626 * |Ver| T | TKL |
627 * +-+-+-+-+-+-+-+-+
628 */
629 return udp->ver_t_tkl & 0x0f;
630}
631
639static inline void *coap_get_token(const coap_pkt_t *pkt)
640{
641 return pkt->buf + sizeof(coap_udp_hdr_t);
642}
643
653static inline unsigned coap_get_total_len(const coap_pkt_t *pkt)
654{
655 return (uintptr_t)pkt->payload - (uintptr_t)pkt->buf + pkt->payload_len;
656}
657
668static inline unsigned coap_get_type(const coap_pkt_t *pkt)
669{
670 return (coap_get_udp_hdr_const(pkt)->ver_t_tkl & 0x30) >> 4;
671}
672
680static inline unsigned coap_get_ver(const coap_pkt_t *pkt)
681{
682 return (coap_get_udp_hdr_const(pkt)->ver_t_tkl & 0x60) >> 6;
683}
684
705bool coap_is_hdr_in_bounds(const coap_pkt_t *pkt, size_t len);
706
714static inline unsigned coap_get_total_hdr_len(const coap_pkt_t *pkt)
715{
716 return sizeof(coap_udp_hdr_t) + coap_get_token_len(pkt);
717}
718
726static inline unsigned coap_get_response_hdr_len(const coap_pkt_t *pkt)
727{
728 return coap_get_total_hdr_len(pkt);
729}
730
737static inline void coap_pkt_set_code(coap_pkt_t *pkt, uint8_t code)
738{
740 hdr->code = code;
741}
742
751static inline void coap_pkt_set_type(coap_pkt_t *pkt, unsigned type)
752{
753 /* assert correct range of type */
754 assert(!(type & ~0x3));
756
757 if (udp) {
758 udp->ver_t_tkl &= ~0x30;
759 udp->ver_t_tkl |= type << 4;
760 }
761}
762
773static inline void coap_pkt_set_tkl(coap_pkt_t *pkt, uint8_t tkl)
774{
775 coap_udp_hdr_t * hdr = coap_get_udp_hdr(pkt);
776 hdr->ver_t_tkl &= 0xf0;
777 hdr->ver_t_tkl |= (tkl & 0x0f);
778}
779
780
797
807uint8_t *coap_find_option(coap_pkt_t *pkt, unsigned opt_num);
808
821uint8_t *coap_iterate_option(coap_pkt_t *pkt, unsigned opt_num,
822 uint8_t **opt_pos, int *opt_len);
823
833
843
856int coap_opt_get_uint(coap_pkt_t *pkt, uint16_t optnum, uint32_t *value);
857
875ssize_t coap_opt_get_string(coap_pkt_t *pkt, uint16_t optnum,
876 char *target, size_t max_len, char separator);
877
893static inline ssize_t coap_get_location_path(coap_pkt_t *pkt,
894 char *target, size_t max_len)
895{
896 return coap_opt_get_string(pkt, COAP_OPT_LOCATION_PATH,
897 target, max_len, '/');
898}
899
915static inline ssize_t coap_get_location_query(coap_pkt_t *pkt,
916 char *target, size_t max_len)
917{
918 return coap_opt_get_string(pkt, COAP_OPT_LOCATION_QUERY,
919 target, max_len, '&');
920}
921
936static inline ssize_t coap_get_uri_path(coap_pkt_t *pkt, char *target)
937{
938 return coap_opt_get_string(pkt, COAP_OPT_URI_PATH, target,
940}
941
955static inline ssize_t coap_get_uri_query_string(coap_pkt_t *pkt, char *target,
956 size_t max_len)
957{
958 return coap_opt_get_string(pkt, COAP_OPT_URI_QUERY,
959 target, max_len, '&');
960}
961
976bool coap_find_uri_query(coap_pkt_t *pkt, const char *key,
977 const char **value, size_t *len);
978
1001 char *key, size_t key_len_max,
1002 char *value, size_t value_len_max);
1003
1034 uint8_t **value, bool init_opt);
1035
1052ssize_t coap_opt_get_opaque(coap_pkt_t *pkt, unsigned opt_num, uint8_t **value);
1054
1067static inline ssize_t coap_get_proxy_uri(coap_pkt_t *pkt, char **target)
1068{
1069 return coap_opt_get_opaque(pkt, COAP_OPT_PROXY_URI, (uint8_t **)target);
1070}
1071
1089void coap_block_object_init(coap_block1_t *block, size_t blknum, size_t blksize,
1090 int more);
1091
1107
1122static inline bool coap_block1_finish(coap_block_slicer_t *slicer)
1123{
1124 return coap_block_finish(slicer);
1125}
1126
1141static inline bool coap_block2_finish(coap_block_slicer_t *slicer)
1142{
1143 return coap_block_finish(slicer);
1144}
1145
1162
1177 size_t blksize);
1178
1197 const void *c, size_t len);
1198
1217 const void *c, size_t len);
1218
1236
1254
1284int coap_get_block(coap_pkt_t *pkt, struct _coap_block *block, uint16_t option);
1285
1310static inline int coap_get_block1(coap_pkt_t *pkt, coap_block1_t *block)
1311{
1312 return coap_get_block(pkt, block, COAP_OPT_BLOCK1);
1313}
1314
1333static inline int coap_get_block2(coap_pkt_t *pkt, coap_block2_t *block)
1334{
1335 return coap_get_block(pkt, block, COAP_OPT_BLOCK2);
1336}
1337
1357
1389 bool more, uint16_t option);
1390
1409static inline ssize_t coap_opt_add_block1(coap_pkt_t *pkt,
1410 coap_block_slicer_t *slicer, bool more)
1411{
1412 return coap_opt_add_block(pkt, slicer, more, COAP_OPT_BLOCK1);
1413}
1414
1433static inline ssize_t coap_opt_add_block2(coap_pkt_t *pkt,
1434 coap_block_slicer_t *slicer, bool more)
1435{
1436 return coap_opt_add_block(pkt, slicer, more, COAP_OPT_BLOCK2);
1437}
1438
1452ssize_t coap_opt_add_uint(coap_pkt_t *pkt, uint16_t optnum, uint32_t value);
1453
1467static inline ssize_t coap_opt_add_block1_control(coap_pkt_t *pkt, coap_block1_t *block) {
1468 return coap_opt_add_uint(pkt, COAP_OPT_BLOCK1,
1469 (block->blknum << 4) | block->szx | (block->more ? 0x8 : 0));
1470}
1471
1485static inline ssize_t coap_opt_add_block2_control(coap_pkt_t *pkt, coap_block1_t *block) {
1486 /* block.more must be zero, so no need to 'or' it in */
1487 return coap_opt_add_uint(pkt, COAP_OPT_BLOCK2,
1488 (block->blknum << 4) | block->szx);
1489}
1490
1504static inline ssize_t coap_opt_add_accept(coap_pkt_t *pkt, uint16_t format)
1505{
1506 return coap_opt_add_uint(pkt, COAP_OPT_ACCEPT, format);
1507}
1508
1522static inline ssize_t coap_opt_add_format(coap_pkt_t *pkt, uint16_t format)
1523{
1524 return coap_opt_add_uint(pkt, COAP_OPT_CONTENT_FORMAT, format);
1525}
1526
1542ssize_t coap_opt_add_opaque(coap_pkt_t *pkt, uint16_t optnum, const void *val, size_t val_len);
1543
1561ssize_t coap_opt_add_uri_query2(coap_pkt_t *pkt, const char *key, size_t key_len,
1562 const char *val, size_t val_len);
1563
1580static inline ssize_t coap_opt_add_uri_query(coap_pkt_t *pkt, const char *key,
1581 const char *val)
1582{
1583 return coap_opt_add_uri_query2(pkt, key, strlen(key), val, val ? strlen(val) : 0);
1584}
1585
1600ssize_t coap_opt_add_proxy_uri(coap_pkt_t *pkt, const char *uri);
1601
1620ssize_t coap_opt_add_chars(coap_pkt_t *pkt, uint16_t optnum, const char *chars,
1621 size_t chars_len, char separator);
1622
1640static inline ssize_t coap_opt_add_string(coap_pkt_t *pkt, uint16_t optnum,
1641 const char *string, char separator)
1642{
1643 return coap_opt_add_chars(pkt, optnum, string, strlen(string), separator);
1644}
1645
1660static inline ssize_t coap_opt_add_uri_path(coap_pkt_t *pkt, const char *path)
1661{
1662 return coap_opt_add_string(pkt, COAP_OPT_URI_PATH, path, '/');
1663}
1664
1680static inline ssize_t coap_opt_add_uri_path_buffer(coap_pkt_t *pkt,
1681 const char *path,
1682 size_t path_len)
1683{
1684 return coap_opt_add_chars(pkt, COAP_OPT_URI_PATH, path, path_len, '/');
1685}
1686
1699ssize_t coap_opt_finish(coap_pkt_t *pkt, uint16_t flags);
1700
1718ssize_t coap_opt_remove(coap_pkt_t *pkt, uint16_t optnum);
1720
1754int coap_builder_init(coap_builder_t *state, void *buf, size_t buf_len,
1755 size_t header_len);
1756
1765static inline bool coap_builder_has_overflown(const coap_builder_t *state)
1766{
1767 return (state->size == 0);
1768}
1769
1780static inline ssize_t coap_builder_msg_size(const coap_builder_t *state)
1781{
1782 if (coap_builder_has_overflown(state)) {
1783 return -EOVERFLOW;
1784 }
1785
1786 return state->pos;
1787}
1788
1799static inline size_t coap_builder_buf_size(const coap_builder_t *state)
1800{
1801 return state->size;
1802}
1803
1811static inline size_t coap_builder_buf_remaining(const coap_builder_t *state)
1812{
1813 if (state->size > state->pos) {
1814 return state->size - state->pos;
1815 }
1816
1817 return 0;
1818}
1819
1843int coap_builder_init_reply(coap_builder_t *state, void *buf, size_t buf_len,
1844 coap_pkt_t *req, uint8_t code);
1845
1867int coap_builder_add_payload(coap_builder_t *state, const void *pld, size_t pld_len);
1868
1895void * coap_builder_allocate_payload(coap_builder_t *state, size_t pld_len);
1896
1911{
1912 return coap_builder_add_payload(state, NULL, 0);
1913}
1914
1934 uint16_t option);
1935
1952static inline int coap_opt_put_block1(coap_builder_t *state,
1953 coap_block_slicer_t *slicer)
1954{
1955 return coap_opt_put_block(state, slicer, COAP_OPT_BLOCK1);
1956}
1957
1974static inline int coap_opt_put_block2(coap_builder_t *state,
1975 coap_block_slicer_t *slicer)
1976{
1977 return coap_opt_put_block(state, slicer, COAP_OPT_BLOCK2);
1978}
1979
1998int coap_opt_put_uint(coap_builder_t *state, uint16_t onum, uint32_t value);
1999
2017 coap_block1_t *block)
2018{
2019 return coap_opt_put_uint(state, COAP_OPT_BLOCK1,
2020 (block->blknum << 4) | block->szx | (block->more ? 0x8 : 0));
2021}
2022
2042 coap_block1_t *block)
2043{
2044 /* block.more must be zero, so no need to 'or' it in */
2045 return coap_opt_put_uint(state, COAP_OPT_BLOCK2,
2046 (block->blknum << 4) | block->szx);
2047}
2048
2065static inline int coap_opt_put_observe(coap_builder_t *state, uint32_t obs)
2066{
2067 obs &= COAP_OBS_MAX_VALUE_MASK; /* trim obs down to 24 bit */
2068 return coap_opt_put_uint(state, COAP_OPT_OBSERVE, obs);
2069}
2070
2092 const char *string, size_t len, char separator);
2112static inline int coap_opt_put_string(coap_builder_t *state, uint16_t optnum,
2113 const char *string, char separator)
2114{
2115 return coap_opt_put_string_with_len(state, optnum,
2116 string, strlen(string), separator);
2117}
2118
2136 const char *location)
2137{
2138 return coap_opt_put_string(state, COAP_OPT_LOCATION_PATH,
2139 location, '/');
2140}
2141
2159 const char *location)
2160{
2161 return coap_opt_put_string(state, COAP_OPT_LOCATION_QUERY,
2162 location, '&');
2163}
2164
2181static inline int coap_opt_put_uri_path(coap_builder_t *state, const char *uri)
2182{
2183 return coap_opt_put_string(state, COAP_OPT_URI_PATH, uri, '/');
2184}
2185
2203 const char *uri_query)
2204{
2205 return coap_opt_put_string(state, COAP_OPT_URI_QUERY, uri_query, '&');
2206}
2207
2231int coap_opt_put_uri_pathquery(coap_builder_t *state, const char *uri);
2232
2249static inline int coap_opt_put_proxy_uri(coap_builder_t *state, const char *uri)
2250{
2251 return coap_opt_put_string(state, COAP_OPT_PROXY_URI, uri, '\0');
2252}
2253
2279
2304int coap_opt_put(coap_builder_t *state, uint16_t onum, const void *odata, size_t olen);
2305
2325 unsigned blknum, unsigned szx, int more)
2326{
2327 return coap_opt_put_uint(state, COAP_OPT_BLOCK1,
2328 (blknum << 4) | szx | (more ? 0x8 : 0));
2329}
2330
2347static inline int coap_opt_put_ct(coap_builder_t *state, uint16_t content_type)
2348{
2349 return coap_opt_put_uint(state, COAP_OPT_CONTENT_FORMAT, content_type);
2350}
2351
2352
2372ssize_t coap_build_udp_hdr(void *buf, size_t buf_len, uint8_t type, const void *token,
2373 size_t token_len, uint8_t code, uint16_t id);
2374
2436ssize_t coap_build_reply(coap_pkt_t *pkt, unsigned code,
2437 uint8_t *rbuf, unsigned rlen, unsigned max_data_len);
2438
2454
2469ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_len,
2470 coap_request_ctx_t *ctx);
2471
2488ssize_t coap_tree_handler(coap_pkt_t *pkt, uint8_t *resp_buf,
2489 unsigned resp_buf_len, coap_request_ctx_t *ctx,
2490 const coap_resource_t *resources,
2491 size_t resources_numof);
2492
2510ssize_t coap_subtree_handler(coap_pkt_t *pkt, uint8_t *resp_buf,
2511 size_t resp_buf_len, coap_request_ctx_t *context);
2512
2520static inline coap_method_flags_t coap_method2flag(unsigned code)
2521{
2522 return (1 << (code - 1));
2523}
2524
2540ssize_t coap_parse_udp(coap_pkt_t *pkt, uint8_t *buf, size_t len);
2541
2556void coap_pkt_init(coap_pkt_t *pkt, uint8_t *buf, size_t len, size_t header_len);
2557
2571static inline void coap_payload_advance_bytes(coap_pkt_t *pkt, size_t len)
2572{
2573 pkt->payload += len;
2574 pkt->payload_len -= len;
2575}
2576
2598ssize_t coap_payload_put_bytes(coap_pkt_t *pkt, const void *data, size_t len);
2599
2613ssize_t coap_payload_put_char(coap_pkt_t *pkt, char c);
2614
2640ssize_t coap_build_reply_header(coap_pkt_t *pkt, unsigned code,
2641 void *buf, size_t len, uint16_t ct,
2642 void **payload, size_t *payload_len_max);
2643
2668 uint8_t code,
2669 uint8_t *buf, size_t len,
2670 uint16_t ct,
2671 const void *payload, size_t payload_len);
2672
2678 uint8_t *buf, size_t len,
2679 coap_request_ctx_t *context);
2681
2685#ifndef CONFIG_NANOCOAP_SERVER_WELL_KNOWN_CORE
2686#define CONFIG_NANOCOAP_SERVER_WELL_KNOWN_CORE !IS_USED(MODULE_GCOAP)
2687#endif
2688
2704int coap_match_path(const coap_resource_t *resource, const char *uri);
2705
2706#if defined(MODULE_GCOAP) || defined(DOXYGEN)
2719static inline bool coap_has_observe(coap_pkt_t *pkt)
2720{
2721 return pkt->observe_value != UINT32_MAX;
2722}
2723
2729static inline void coap_clear_observe(coap_pkt_t *pkt)
2730{
2731 pkt->observe_value = UINT32_MAX;
2732}
2733
2741static inline uint32_t coap_get_observe(coap_pkt_t *pkt)
2742{
2743 return pkt->observe_value;
2744}
2745
2746#endif
2747
2751#define COAP_WELL_KNOWN_CORE_DEFAULT_HANDLER \
2752 { \
2753 .path = "/.well-known/core", \
2754 .methods = COAP_GET, \
2755 .handler = coap_well_known_core_default_handler \
2756 }
2757
2758#ifdef __cplusplus
2759}
2760#endif
POSIX.1-2008 compliant version of the assert macro.
#define assert(cond)
abort the program if assertion is false
Definition assert.h:143
Bitfield 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:520
static uint16_t htons(uint16_t v)
Convert from host byte order to network byte order, 16 bit.
Definition byteorder.h:505
#define WARN_UNUSED_RESULT
Attribute to add to a function whose return value should not silently be discarded.
#define EOVERFLOW
Value too large to be stored in data type.
Definition errno.h:133
#define COAP_OBS_MAX_VALUE_MASK
observe value is 24 bits
Definition coap.h:533
coap_method_t
CoAP method codes used in request.
Definition coap.h:171
#define CONFIG_NANOCOAP_NOPTS_MAX
Maximum number of Options in a message.
Definition nanocoap.h:129
#define CONFIG_NANOCOAP_URI_MAX
Maximum length of a resource path string read from or written to a message.
Definition nanocoap.h:137
uint32_t coap_request_ctx_get_tl_type(const coap_request_ctx_t *ctx)
Get transport the packet was received over.
uint8_t * coap_find_option(coap_pkt_t *pkt, unsigned opt_num)
Get pointer to an option field by type.
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:1580
int coap_blockwise_put_char(coap_builder_t *state, coap_block_slicer_t *slicer, char c)
Add a single character to a block2 reply when building the response using a coap_builder_t structure ...
int coap_opt_put_block(coap_builder_t *state, coap_block_slicer_t *slicer, uint16_t option)
Insert block option into buffer.
ssize_t coap_opt_get_string(coap_pkt_t *pkt, uint16_t optnum, char *target, size_t max_len, char separator)
Read a full option as null terminated string into the target buffer.
int coap_match_path(const coap_resource_t *resource, const char *uri)
Checks if a CoAP resource path matches a given URI.
bool coap_is_hdr_in_bounds(const coap_pkt_t *pkt, size_t len)
Validate that the header of pkt is no longer than len bytes.
WARN_UNUSED_RESULT int coap_get_block(coap_pkt_t *pkt, struct _coap_block *block, uint16_t option)
Internal Block Option getter.
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:737
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:1433
static unsigned coap_get_code_raw(const coap_pkt_t *pkt)
Get a message's raw code (class + detail)
Definition nanocoap.h:535
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.
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:1522
int coap_blockwise_put_char_pkt(coap_pkt_t *pdu, coap_block_slicer_t *slicer, char c)
Add a single character to a block2 reply when building the response using a coap_pkt_t structure to a...
static uint8_t coap_code(unsigned cls, unsigned detail)
Encode given code class and code detail to raw code.
Definition nanocoap.h:523
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:1660
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:955
static ssize_t coap_get_location_path(coap_pkt_t *pkt, char *target, size_t max_len)
Convenience function for getting the packet's LOCATION_PATH option.
Definition nanocoap.h:893
static int coap_opt_put_block2(coap_builder_t *state, coap_block_slicer_t *slicer)
Insert block2 option into buffer.
Definition nanocoap.h:1974
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 size_t coap_builder_buf_size(const coap_builder_t *state)
Get the size of the buffer in state.
Definition nanocoap.h:1799
static unsigned coap_get_id(const coap_pkt_t *pkt)
Get the message ID of the given CoAP packet.
Definition nanocoap.h:595
bool coap_block_finish(coap_block_slicer_t *slicer)
Finish a block request (block1 or block2)
static int coap_opt_put_ct(coap_builder_t *state, uint16_t content_type)
Insert content type option into buffer.
Definition nanocoap.h:2347
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:1504
static int coap_opt_put_location_path(coap_builder_t *state, const char *location)
Convenience function for inserting LOCATION_PATH option into buffer.
Definition nanocoap.h:2135
int coap_builder_add_payload(coap_builder_t *state, const void *pld, size_t pld_len)
Add a payload marker and payload with bounds checking.
static int coap_opt_put_uri_path(coap_builder_t *state, const char *uri)
Convenience function for inserting URI_PATH option into buffer.
Definition nanocoap.h:2181
void * coap_builder_allocate_payload(coap_builder_t *state, size_t pld_len)
Write the payload marker into the current position of state and allocate pld_len bytes of payload aft...
void coap_request_ctx_init(coap_request_ctx_t *ctx, sock_udp_ep_t *remote)
Initialize CoAP request context.
ssize_t coap_payload_put_bytes(coap_pkt_t *pkt, const void *data, size_t len)
Add payload data to the CoAP request.
static int coap_opt_put_proxy_uri(coap_builder_t *state, const char *uri)
Convenience function for inserting PROXY_URI option into buffer.
Definition nanocoap.h:2249
static ssize_t coap_get_location_query(coap_pkt_t *pkt, char *target, size_t max_len)
Convenience function for getting the packet's LOCATION_QUERY option.
Definition nanocoap.h:915
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...
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.
uint16_t coap_method_flags_t
Method flag type.
Definition nanocoap.h:295
ssize_t coap_build_udp_hdr(void *buf, size_t buf_len, uint8_t type, const void *token, size_t token_len, uint8_t code, uint16_t id)
Build a CoAP over UDP header.
static coap_udp_hdr_t * coap_get_udp_hdr(coap_pkt_t *pkt)
Get the CoAP header of a CoAP over UDP packet.
Definition nanocoap.h:500
static unsigned coap_get_ver(const coap_pkt_t *pkt)
Get the CoAP version number.
Definition nanocoap.h:680
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.
ssize_t coap_parse_udp(coap_pkt_t *pkt, uint8_t *buf, size_t len)
Parse a CoAP PDU in UDP / DTLS format.
static bool coap_block2_finish(coap_block_slicer_t *slicer)
Finish a block2 response.
Definition nanocoap.h:1141
int coap_opt_put_uint(coap_builder_t *state, uint16_t onum, uint32_t value)
Encode the given uint option into buffer.
static coap_method_t coap_get_method(const coap_pkt_t *pkt)
Get a request's method type.
Definition nanocoap.h:583
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:714
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 void coap_pkt_set_type(coap_pkt_t *pkt, unsigned type)
Set the message type for the given CoAP packet.
Definition nanocoap.h:751
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:547
int coap_opt_put_uri_pathquery(coap_builder_t *state, const char *uri)
Convenience function for inserting URI_PATH and URI_QUERY into buffer This function will automaticall...
static ssize_t coap_builder_msg_size(const coap_builder_t *state)
Get the size of the CoAP message in state.
Definition nanocoap.h:1780
int coap_blockwise_put_bytes(coap_builder_t *state, coap_block_slicer_t *slicer, const void *c, size_t len)
Add a byte array to a block2 reply when building the response using a coap_builder_t structure to ass...
int coap_blockwise_put_bytes_pkt(coap_pkt_t *pdu, coap_block_slicer_t *slicer, const void *c, size_t len)
Add a byte array to a block2 reply when building the response using a coap_pkt_t structure to assembl...
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:1640
ssize_t coap_build_empty_ack(const coap_pkt_t *pkt, coap_udp_hdr_t *ack)
Build empty reply to CoAP request.
WARN_UNUSED_RESULT int coap_block2_init(coap_pkt_t *pkt, coap_block_slicer_t *slicer)
Initialize a block2 slicer struct for writing the payload.
int coap_put_block1_ok(coap_builder_t *state, coap_block1_t *block1)
Insert block1 option into buffer (from coap_block1_t)
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:559
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:261
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 void coap_payload_advance_bytes(coap_pkt_t *pkt, size_t len)
Advance the payload pointer.
Definition nanocoap.h:2571
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:2741
static WARN_UNUSED_RESULT int coap_get_block1(coap_pkt_t *pkt, coap_block1_t *block)
Block1 option getter.
Definition nanocoap.h:1310
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:1485
static unsigned coap_get_type(const coap_pkt_t *pkt)
Get the message type.
Definition nanocoap.h:668
static int coap_opt_put_uri_query(coap_builder_t *state, const char *uri_query)
Convenience function for inserting URI_QUERY option into buffer.
Definition nanocoap.h:2202
static int coap_opt_put_string(coap_builder_t *state, uint16_t optnum, const char *string, char separator)
Encode the given string as multi-part option into buffer.
Definition nanocoap.h:2112
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:571
static void coap_pkt_set_tkl(coap_pkt_t *pkt, uint8_t tkl)
Set the message token length for the given CoAP packet.
Definition nanocoap.h:773
static int coap_opt_put_block1(coap_builder_t *state, coap_block_slicer_t *slicer)
Insert block1 option into buffer.
Definition nanocoap.h:1952
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:726
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.
static int coap_opt_put_block2_control(coap_builder_t *state, coap_block1_t *block)
Insert block2 option into buffer in control usage.
Definition nanocoap.h:2041
struct _coap_block coap_block1_t
Block1 helper struct.
Definition nanocoap.h:447
static int coap_opt_put_block1_control(coap_builder_t *state, coap_block1_t *block)
Insert block1 option into buffer in control usage.
Definition nanocoap.h:2016
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:1680
static void * coap_get_token(const coap_pkt_t *pkt)
Get pointer to a message's token.
Definition nanocoap.h:639
ssize_t coap_reply_simple(coap_pkt_t *pkt, uint8_t code, uint8_t *buf, size_t len, uint16_t ct, const void *payload, size_t payload_len)
Create CoAP reply (convenience function)
static const coap_udp_hdr_t * coap_get_udp_hdr_const(const coap_pkt_t *pkt)
Same as coap_get_udp_hdr but for const memory.
Definition nanocoap.h:509
static bool coap_block1_finish(coap_block_slicer_t *slicer)
Finish a block1 request.
Definition nanocoap.h:1122
static int coap_opt_put_observe(coap_builder_t *state, uint32_t obs)
Insert an CoAP Observe Option into the buffer.
Definition nanocoap.h:2065
void * coap_request_ctx_get_context(const coap_request_ctx_t *ctx)
Get resource context associated with a CoAP request.
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)
ssize_t coap_opt_add_proxy_uri(coap_pkt_t *pkt, const char *uri)
Adds a single Proxy-URI option into pkt.
static size_t coap_builder_buf_remaining(const coap_builder_t *state)
Get the remaining free buffer space in state.
Definition nanocoap.h:1811
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:276
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.
int(* coap_request_cb_t)(void *arg, coap_pkt_t *pkt)
Coap request callback descriptor.
Definition nanocoap.h:288
static int coap_opt_put_location_query(coap_builder_t *state, const char *location)
Convenience function for inserting LOCATION_QUERY option into buffer.
Definition nanocoap.h:2158
WARN_UNUSED_RESULT int coap_builder_init_reply(coap_builder_t *state, void *buf, size_t buf_len, coap_pkt_t *req, uint8_t code)
Initialize state for building a response and add the response header with matching token and suitable...
const char * coap_request_ctx_get_path(const coap_request_ctx_t *ctx)
Get resource path associated with a CoAP request.
static WARN_UNUSED_RESULT int coap_get_block2(coap_pkt_t *pkt, coap_block2_t *block)
Block2 option getter.
Definition nanocoap.h:1333
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.
static ssize_t coap_get_uri_path(coap_pkt_t *pkt, char *target)
Convenience function for getting the packet's URI_PATH.
Definition nanocoap.h:936
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.
static bool coap_builder_has_overflown(const coap_builder_t *state)
Check if building the message failed due to insufficient buffer space.
Definition nanocoap.h:1765
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.
WARN_UNUSED_RESULT int coap_block_slicer_init(coap_block_slicer_t *slicer, size_t blknum, size_t blksize)
Initialize a block slicer struct from content information.
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:1067
static int coap_builder_add_payload_marker(coap_builder_t *state)
Add a payload marker with bounds checking.
Definition nanocoap.h:1910
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:653
int coap_opt_put_string_with_len(coap_builder_t *state, uint16_t optnum, const char *string, size_t len, char separator)
Encode the given string as multi-part option into buffer.
struct _coap_request_ctx coap_request_ctx_t
Forward declaration of internal CoAP resource request handler context.
Definition nanocoap.h:237
static bool coap_has_observe(coap_pkt_t *pkt)
Identifies a packet containing an observe option.
Definition nanocoap.h:2719
int coap_opt_put(coap_builder_t *state, uint16_t onum, const void *odata, size_t olen)
Insert a CoAP option into buffer.
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:1409
static coap_method_flags_t coap_method2flag(unsigned code)
Convert message code (request method) into a corresponding bit field.
Definition nanocoap.h:2520
struct _coap_block coap_block2_t
Block2 helper struct.
Definition nanocoap.h:452
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:1467
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 void coap_set_id(coap_pkt_t *pkt, uint16_t id)
Set the message ID of the given CoAP packet.
Definition nanocoap.h:606
static unsigned coap_get_token_len(const coap_pkt_t *pkt)
Get a message's token length [in byte].
Definition nanocoap.h:618
static void coap_clear_observe(coap_pkt_t *pkt)
Clears the observe option value from a packet.
Definition nanocoap.h:2729
ssize_t coap_opt_finish(coap_pkt_t *pkt, uint16_t flags)
Finalizes options as required and prepares for payload.
int coap_builder_init(coap_builder_t *state, void *buf, size_t buf_len, size_t header_len)
Initialize state for building a message.
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.
static int coap_opt_put_block1_raw(coap_builder_t *state, unsigned blknum, unsigned szx, int more)
Insert block1 option into buffer.
Definition nanocoap.h:2324
struct _sock_tl_ep sock_udp_ep_t
An end point for a UDP sock object.
Definition udp.h:292
struct iolist iolist_t
iolist forward declaration
Definition iolist.h:30
iolist scatter / gather IO
Common macros and compiler attributes/pragmas configuration.
Generic CoAP values as defined by RFC7252.
UDP sock definitions.
Block1 helper struct.
Definition nanocoap.h:437
uint32_t blknum
block number
Definition nanocoap.h:439
size_t offset
offset of received data
Definition nanocoap.h:438
bool more
0 for last block, 1 for more blocks coming
Definition nanocoap.h:441
uint8_t szx
szx value
Definition nanocoap.h:440
CoAP resource request handler context.
Definition nanocoap.h:327
sock_udp_ep_t * local
Definition nanocoap.h:336
const coap_resource_t * resource
resource of the request
Definition nanocoap.h:328
sock_udp_ep_t * local_udp
local UDP endpoint of the request
Definition nanocoap.h:335
sock_udp_ep_t * remote
Definition nanocoap.h:331
uint32_t tl_type
transport the packet was received over
Definition nanocoap.h:346
sock_udp_ep_t * remote_udp
remote UDP endpoint of the request
Definition nanocoap.h:330
Blockwise transfer helper struct.
Definition nanocoap.h:457
size_t end
End offset of the current block.
Definition nanocoap.h:459
size_t start
Start offset of the current block.
Definition nanocoap.h:458
uint8_t * opt_value
Pointer to the value of the placed option.
Definition nanocoap.h:461
size_t cur
Offset of the generated content.
Definition nanocoap.h:460
Structure to hold the state for building a CoAP message.
Definition nanocoap.h:422
uint16_t last_opt_num
Number of the last option added (for delta-encoding)
Definition nanocoap.h:426
uint16_t pos
Position of the next byte to write within buf
Definition nanocoap.h:424
uint16_t size
Size of buf in bytes.
Definition nanocoap.h:425
uint8_t * buf
Buffer to build the message into.
Definition nanocoap.h:423
CoAP option array entry.
Definition nanocoap.h:193
uint16_t offset
offset in packet
Definition nanocoap.h:195
uint16_t opt_num
full CoAP option number
Definition nanocoap.h:194
CoAP PDU parsing context structure.
Definition nanocoap.h:216
coap_optpos_t options[CONFIG_NANOCOAP_NOPTS_MAX]
option offset array
Definition nanocoap.h:227
uint8_t * payload
pointer to end of the header
Definition nanocoap.h:223
uint16_t payload_len
length of payload
Definition nanocoap.h:225
uint16_t options_len
length of options array
Definition nanocoap.h:226
uint8_t * buf
pointer to the beginning of the buffer holding the pkt
Definition nanocoap.h:222
BITFIELD(opt_crit, CONFIG_NANOCOAP_NOPTS_MAX)
unhandled critical option
iolist_t * snips
payload snips (optional)
Definition nanocoap.h:224
Type for CoAP resource subtrees.
Definition nanocoap.h:310
const size_t resources_numof
number of entries in array
Definition nanocoap.h:312
const coap_resource_t * resources
ptr to resource array
Definition nanocoap.h:311
Type for CoAP resource entry.
Definition nanocoap.h:300
const char * path
URI path of resource.
Definition nanocoap.h:301
coap_method_flags_t methods
OR'ed methods this resource allows.
Definition nanocoap.h:302
coap_handler_t handler
ptr to resource handler
Definition nanocoap.h:303
void * context
ptr to user defined context data
Definition nanocoap.h:304
Raw CoAP over UDP PDU header structure.
Definition nanocoap.h:184
uint8_t code
CoAP code (e.g.m 205)
Definition nanocoap.h:186
uint8_t ver_t_tkl
version, token, token length
Definition nanocoap.h:185
uint16_t id
Req/resp ID.
Definition nanocoap.h:187
Cross File Arrays.