nanocoap.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016-17 Kaspar Schleiser <kaspar@schleiser.de>
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser
5  * General Public License v2.1. See the file LICENSE in the top level
6  * directory for more details.
7  */
8 
23 #ifndef NET_NANOCOAP_H
24 #define NET_NANOCOAP_H
25 
26 #include <assert.h>
27 #include <stdint.h>
28 #include <stdbool.h>
29 #include <stddef.h>
30 #include <unistd.h>
31 
32 #ifdef RIOT_VERSION
33 #include "byteorder.h"
34 #else
35 #include <arpa/inet.h>
36 #endif
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
45 #define COAP_PORT (5683)
46 
51 #define NANOCOAP_NOPTS_MAX (16)
52 #define NANOCOAP_URI_MAX (64)
53 
55 #ifdef MODULE_GCOAP
56 #define NANOCOAP_URL_MAX NANOCOAP_URI_MAX
57 #define NANOCOAP_QS_MAX (64)
58 #endif
59 
64 #define COAP_OPT_URI_HOST (3)
65 #define COAP_OPT_OBSERVE (6)
66 #define COAP_OPT_URI_PATH (11)
67 #define COAP_OPT_CONTENT_FORMAT (12)
68 #define COAP_OPT_URI_QUERY (15)
69 #define COAP_OPT_BLOCK2 (23)
70 #define COAP_OPT_BLOCK1 (27)
71 
77 #define COAP_REQ (0)
78 #define COAP_RESP (2)
79 #define COAP_RST (3)
80 
85 #define COAP_TYPE_CON (0)
86 #define COAP_TYPE_NON (1)
87 #define COAP_TYPE_ACK (2)
88 #define COAP_TYPE_RST (3)
89 
95 #define COAP_CLASS_REQ (0)
96 #define COAP_METHOD_GET (1)
97 #define COAP_METHOD_POST (2)
98 #define COAP_METHOD_PUT (3)
99 #define COAP_METHOD_DELETE (4)
100 
106 #define COAP_GET (0x1)
107 #define COAP_POST (0x2)
108 #define COAP_PUT (0x4)
109 #define COAP_DELETE (0x8)
110 
116 #define COAP_CODE_EMPTY (0)
117 
123 #define COAP_CLASS_SUCCESS (2)
124 #define COAP_CODE_CREATED ((2 << 5) | 1)
125 #define COAP_CODE_DELETED ((2 << 5) | 2)
126 #define COAP_CODE_VALID ((2 << 5) | 3)
127 #define COAP_CODE_CHANGED ((2 << 5) | 4)
128 #define COAP_CODE_204 ((2 << 5) | 4)
129 #define COAP_CODE_CONTENT ((2 << 5) | 5)
130 #define COAP_CODE_205 ((2 << 5) | 5)
131 #define COAP_CODE_231 ((2 << 5) | 31)
132 
138 #define COAP_CLASS_CLIENT_FAILURE (4)
139 #define COAP_CODE_BAD_REQUEST ((4 << 5) | 0)
140 #define COAP_CODE_UNAUTHORIZED ((4 << 5) | 1)
141 #define COAP_CODE_BAD_OPTION ((4 << 5) | 2)
142 #define COAP_CODE_FORBIDDEN ((4 << 5) | 3)
143 #define COAP_CODE_PATH_NOT_FOUND ((4 << 5) | 4)
144 #define COAP_CODE_404 ((4 << 5) | 4)
145 #define COAP_CODE_METHOD_NOT_ALLOWED ((4 << 5) | 5)
146 #define COAP_CODE_NOT_ACCEPTABLE ((4 << 5) | 6)
147 #define COAP_CODE_REQUEST_ENTITY_INCOMPLETE ((4 << 5) | 8)
148 #define COAP_CODE_PRECONDITION_FAILED ((4 << 5) | 0xC)
149 #define COAP_CODE_REQUEST_ENTITY_TOO_LARGE ((4 << 5) | 0xD)
150 #define COAP_CODE_UNSUPPORTED_CONTENT_FORMAT ((4 << 5) | 0xF)
151 
157 #define COAP_CLASS_SERVER_FAILURE (5)
158 #define COAP_CODE_INTERNAL_SERVER_ERROR ((5 << 5) | 0)
159 #define COAP_CODE_NOT_IMPLEMENTED ((5 << 5) | 1)
160 #define COAP_CODE_BAD_GATEWAY ((5 << 5) | 2)
161 #define COAP_CODE_SERVICE_UNAVAILABLE ((5 << 5) | 3)
162 #define COAP_CODE_GATEWAY_TIMEOUT ((5 << 5) | 4)
163 #define COAP_CODE_PROXYING_NOT_SUPPORTED ((5 << 5) | 5)
164 
170 #define COAP_CT_LINK_FORMAT (40)
171 #define COAP_CT_XML (41)
172 #define COAP_CT_OCTET_STREAM (42)
173 #define COAP_CT_EXI (47)
174 #define COAP_CT_JSON (50)
175 
181 #define COAP_FORMAT_TEXT (0)
182 #define COAP_FORMAT_LINK (40)
183 #define COAP_FORMAT_OCTET (42)
184 #define COAP_FORMAT_JSON (50)
185 #define COAP_FORMAT_CBOR (60)
186 
187 #define COAP_FORMAT_NONE (65535)
188 
194 #define COAP_OBS_REGISTER (0)
195 #define COAP_OBS_DEREGISTER (1)
196 
202 #define COAP_ACK_TIMEOUT (2U)
203 #define COAP_RANDOM_FACTOR (1.5)
204 
212 #define COAP_ACK_VARIANCE (1U)
213 #define COAP_MAX_RETRANSMIT (4)
214 #define COAP_NSTART (1)
215 #define COAP_DEFAULT_LEISURE (5)
216 
222 #define COAP_BLOCKWISE_NUM_OFF (4)
223 #define COAP_BLOCKWISE_MORE_OFF (3)
224 #define COAP_BLOCKWISE_SZX_MASK (0x07)
225 #define COAP_BLOCKWISE_SZX_MAX (7)
226 
235 #define COAP_OPT_FINISH_NONE (0x0000)
236 
237 #define COAP_OPT_FINISH_PAYLOAD (0x0001)
238 
243 typedef struct __attribute__((packed)) {
244  uint8_t ver_t_tkl;
245  uint8_t code;
246  uint16_t id;
247  uint8_t data[];
248 } coap_hdr_t;
249 
253 typedef struct {
254  uint16_t opt_num;
255  uint16_t offset;
256 } coap_optpos_t;
257 
261 typedef struct {
263  uint8_t *token;
264  uint8_t *payload;
265  uint16_t payload_len;
266  uint16_t options_len;
267  coap_optpos_t options[NANOCOAP_NOPTS_MAX];
268 #ifdef MODULE_GCOAP
269  uint8_t url[NANOCOAP_URI_MAX];
270  uint8_t qs[NANOCOAP_QS_MAX];
271  uint16_t content_type;
272  uint32_t observe_value;
273 #endif
274 } coap_pkt_t;
275 
279 typedef ssize_t (*coap_handler_t)(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context);
280 
284 typedef struct {
285  const char *path;
286  unsigned methods;
288  void *context;
290 
294 typedef struct {
295  size_t offset;
296  uint32_t blknum;
297  unsigned szx;
298  int more;
300 } coap_block1_t;
301 
305 extern const coap_resource_t coap_resources[];
306 
310 extern const unsigned coap_resources_numof;
311 
326 int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len);
327 
345 ssize_t coap_build_reply(coap_pkt_t *pkt, unsigned code,
346  uint8_t *rbuf, unsigned rlen, unsigned payload_len);
347 
369  unsigned code,
370  uint8_t *buf, size_t len,
371  unsigned ct,
372  const uint8_t *payload, uint8_t payload_len);
373 
387 ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_len);
388 
403 ssize_t coap_build_hdr(coap_hdr_t *hdr, unsigned type, uint8_t *token,
404  size_t token_len, unsigned code, uint16_t id);
405 
420 void coap_pkt_init(coap_pkt_t *pkt, uint8_t *buf, size_t len, size_t header_len);
421 
438 size_t coap_put_option(uint8_t *buf, uint16_t lastonum, uint16_t onum, uint8_t *odata, size_t olen);
439 
450 size_t coap_put_option_ct(uint8_t *buf, uint16_t lastonum, uint16_t content_type);
451 
463 size_t coap_put_option_uri(uint8_t *buf, uint16_t lastonum, const char *uri, uint16_t optnum);
464 
477 int coap_get_blockopt(coap_pkt_t *pkt, uint16_t option, uint32_t *blknum, unsigned *szx);
478 
496 int coap_get_block1(coap_pkt_t *pkt, coap_block1_t *block1);
497 
510 size_t coap_put_option_block1(uint8_t *buf, uint16_t lastonum, unsigned blknum, unsigned szx, int more);
511 
529 size_t coap_put_block1_ok(uint8_t *pkt_pos, coap_block1_t *block1, uint16_t lastonum);
530 
547 ssize_t coap_opt_add_string(coap_pkt_t *pkt, uint16_t optnum, const char *string, char separator);
548 
562 ssize_t coap_opt_add_uint(coap_pkt_t *pkt, uint16_t optnum, uint32_t value);
563 
575 ssize_t coap_opt_finish(coap_pkt_t *pkt, uint16_t flags);
576 
585 unsigned coap_get_content_type(coap_pkt_t *pkt);
586 
601 int coap_get_uri(coap_pkt_t *pkt, uint8_t *target);
602 
610 static inline unsigned coap_szx2size(unsigned szx)
611 {
612  return (1 << (szx + 4));
613 }
614 
622 static inline unsigned coap_get_ver(coap_pkt_t *pkt)
623 {
624  return (pkt->hdr->ver_t_tkl & 0x60) >> 6;
625 }
626 
637 static inline unsigned coap_get_type(coap_pkt_t *pkt)
638 {
639  return (pkt->hdr->ver_t_tkl & 0x30) >> 4;
640 }
641 
649 static inline unsigned coap_get_token_len(coap_pkt_t *pkt)
650 {
651  return (pkt->hdr->ver_t_tkl & 0xf);
652 }
653 
661 static inline unsigned coap_get_code_class(coap_pkt_t *pkt)
662 {
663  return pkt->hdr->code >> 5;
664 }
665 
673 static inline unsigned coap_get_code_detail(coap_pkt_t *pkt)
674 {
675  return pkt->hdr->code & 0x1f;
676 }
677 
685 static inline unsigned coap_get_code_raw(coap_pkt_t *pkt)
686 {
687  return (unsigned)pkt->hdr->code;
688 }
689 
697 static inline unsigned coap_get_code(coap_pkt_t *pkt)
698 {
699  return (coap_get_code_class(pkt) * 100) + coap_get_code_detail(pkt);
700 }
701 
709 static inline unsigned coap_get_id(coap_pkt_t *pkt)
710 {
711  return ntohs(pkt->hdr->id);
712 }
713 
721 static inline unsigned coap_get_total_hdr_len(coap_pkt_t *pkt)
722 {
723  return sizeof(coap_hdr_t) + coap_get_token_len(pkt);
724 }
725 
734 static inline uint8_t coap_code(unsigned class, unsigned detail)
735 {
736  return (class << 5) | detail;
737 }
738 
745 static inline void coap_hdr_set_code(coap_hdr_t *hdr, uint8_t code)
746 {
747  hdr->code = code;
748 }
749 
758 static inline void coap_hdr_set_type(coap_hdr_t *hdr, unsigned type)
759 {
760  /* assert correct range of type */
761  assert(!(type & ~0x3));
762 
763  hdr->ver_t_tkl &= ~0x30;
764  hdr->ver_t_tkl |= type << 4;
765 }
766 
774 static inline unsigned coap_method2flag(unsigned code)
775 {
776  return (1 << (code - 1));
777 }
778 
779 #if defined(MODULE_GCOAP) || defined(DOXYGEN)
780 
788 static inline bool coap_has_observe(coap_pkt_t *pkt)
789 {
790  return pkt->observe_value != UINT32_MAX;
791 }
792 
798 static inline void coap_clear_observe(coap_pkt_t *pkt)
799 {
800  pkt->observe_value = UINT32_MAX;
801 }
802 
810 static inline uint32_t coap_get_observe(coap_pkt_t *pkt)
811 {
812  return pkt->observe_value;
813 }
814 #endif
815 
821  uint8_t *buf, size_t len,
822  void *context);
823 
827 #define COAP_WELL_KNOWN_CORE_DEFAULT_HANDLER \
828  { \
829  .path = "/.well-known/core", \
830  .methods = COAP_GET, \
831  .handler = coap_well_known_core_default_handler \
832  }
833 
834 #ifdef __cplusplus
835 }
836 #endif
837 #endif /* NET_NANOCOAP_H */
838 
static void coap_hdr_set_type(coap_hdr_t *hdr, unsigned type)
Set the message type for the given CoAP header.
Definition: nanocoap.h:758
static unsigned coap_get_code_raw(coap_pkt_t *pkt)
Get a message&#39;s raw code (class + detail)
Definition: nanocoap.h:685
static unsigned coap_get_code_detail(coap_pkt_t *pkt)
Get a message&#39;s code detail (5 least significant bits of code)
Definition: nanocoap.h:673
int coap_get_block1(coap_pkt_t *pkt, coap_block1_t *block1)
Block1 option getter.
int coap_get_blockopt(coap_pkt_t *pkt, uint16_t option, uint32_t *blknum, unsigned *szx)
Generic block option getter.
const unsigned coap_resources_numof
Number of entries in global CoAP resource list.
uint32_t blknum
block number
Definition: nanocoap.h:296
static unsigned coap_get_code_class(coap_pkt_t *pkt)
Get a message&#39;s code class (3 most significant bits of code)
Definition: nanocoap.h:661
size_t coap_put_option_ct(uint8_t *buf, uint16_t lastonum, uint16_t content_type)
Insert content type option into buffer.
ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_len)
Handle incoming CoAP request.
Raw CoAP PDU header structure.
Definition: nanocoap.h:243
static unsigned coap_szx2size(unsigned szx)
Helper to decode SZX value to size in bytes.
Definition: nanocoap.h:610
void * context
ptr to user defined context data
Definition: nanocoap.h:288
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.
uint16_t payload_len
length of payload
Definition: nanocoap.h:265
size_t coap_put_option_uri(uint8_t *buf, uint16_t lastonum, const char *uri, uint16_t optnum)
Insert URI encoded option into buffer.
CoAP option array entry.
Definition: nanocoap.h:253
uint8_t * token
pointer to token
Definition: nanocoap.h:263
uint8_t code
CoAP code (e.g.m 205)
Definition: nanocoap.h:245
ssize_t coap_build_hdr(coap_hdr_t *hdr, unsigned type, uint8_t *token, size_t token_len, unsigned code, uint16_t id)
Builds a CoAP header.
Type for CoAP resource entry.
Definition: nanocoap.h:284
static unsigned coap_get_total_hdr_len(coap_pkt_t *pkt)
Get the total header length (4-byte header + token length)
Definition: nanocoap.h:721
POSIX.1-2008 compliant version of the assert macro.
signed int ssize_t
Used for a count of bytes or an error indication.
Definition: msp430_types.h:89
coap_hdr_t * hdr
pointer to raw packet
Definition: nanocoap.h:262
static void coap_clear_observe(coap_pkt_t *pkt)
Clears the observe option value from a packet.
Definition: nanocoap.h:798
unsigned coap_get_content_type(coap_pkt_t *pkt)
Get content type from packet.
static uint8_t coap_code(unsigned class, unsigned detail)
Encode given code class and code detail to raw code.
Definition: nanocoap.h:734
uint16_t opt_num
full CoAP option number
Definition: nanocoap.h:254
#define assert(cond)
abort the program if assertion is false
Definition: assert.h:104
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:745
ssize_t coap_opt_finish(coap_pkt_t *pkt, uint16_t flags)
Finalizes options as required and prepares for payload.
unsigned methods
OR&#39;ed methods this resource allows.
Definition: nanocoap.h:286
static unsigned coap_get_ver(coap_pkt_t *pkt)
Get the CoAP version number.
Definition: nanocoap.h:622
const char * path
URI path of resource.
Definition: nanocoap.h:285
uint16_t options_len
length of options array
Definition: nanocoap.h:266
uint8_t ver_t_tkl
version, token, token length
Definition: nanocoap.h:244
Block1 helper struct.
Definition: nanocoap.h:294
int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len)
Parse a CoAP PDU.
static unsigned coap_get_id(coap_pkt_t *pkt)
Get the message ID of the given CoAP packet.
Definition: nanocoap.h:709
size_t offset
offset of received data
Definition: nanocoap.h:295
ssize_t coap_reply_simple(coap_pkt_t *pkt, unsigned code, uint8_t *buf, size_t len, unsigned ct, const uint8_t *payload, uint8_t payload_len)
Create CoAP reply (convenience function)
ssize_t coap_build_reply(coap_pkt_t *pkt, unsigned code, uint8_t *rbuf, unsigned rlen, unsigned payload_len)
Build reply to CoAP request.
static uint32_t coap_get_observe(coap_pkt_t *pkt)
Get the value of the observe option from the given packet.
Definition: nanocoap.h:810
Functions to work with different byte orders.
static unsigned coap_get_token_len(coap_pkt_t *pkt)
Get a message&#39;s token length [in byte].
Definition: nanocoap.h:649
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.
size_t coap_put_option_block1(uint8_t *buf, uint16_t lastonum, unsigned blknum, unsigned szx, int more)
Insert block1 option into buffer.
Definitions for internet operations.
ssize_t coap_well_known_core_default_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context)
Reference to the default .well-known/core handler defined by the application.
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)
uint8_t * payload
pointer to payload
Definition: nanocoap.h:264
static unsigned coap_method2flag(unsigned code)
Convert message code (request method) into a corresponding bit field.
Definition: nanocoap.h:774
ssize_t coap_opt_add_uint(coap_pkt_t *pkt, uint16_t optnum, uint32_t value)
Encode the given uint option into pkt.
uint16_t offset
offset in packet
Definition: nanocoap.h:255
unsigned szx
szx value
Definition: nanocoap.h:297
uint16_t id
Req/resp ID.
Definition: nanocoap.h:246
static bool coap_has_observe(coap_pkt_t *pkt)
Identifies a packet containing an observe option.
Definition: nanocoap.h:788
int coap_get_uri(coap_pkt_t *pkt, uint8_t *target)
Get the packet&#39;s request URI.
coap_handler_t handler
ptr to resource handler
Definition: nanocoap.h:287
static unsigned coap_get_type(coap_pkt_t *pkt)
Get the message type.
Definition: nanocoap.h:637
ssize_t(* coap_handler_t)(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context)
Resource handler type.
Definition: nanocoap.h:279
int more
-1 for no option, 0 for last block, 1 for more blocks coming
Definition: nanocoap.h:298
static unsigned coap_get_code(coap_pkt_t *pkt)
Get a message&#39;s code in decimal format ((class * 100) + detail)
Definition: nanocoap.h:697
CoAP PDU parsing context structure.
Definition: nanocoap.h:261
size_t coap_put_option(uint8_t *buf, uint16_t lastonum, uint16_t onum, uint8_t *odata, size_t olen)
Insert a CoAP option into buffer.
const coap_resource_t coap_resources[]
Global CoAP resource list.
static uint16_t ntohs(uint16_t v)
Convert from network byte order to host byte order, 16 bit.
Definition: byteorder.h:428