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 
22 #ifndef NET_NANOCOAP_H
23 #define NET_NANOCOAP_H
24 
25 #include <assert.h>
26 #include <stdint.h>
27 #include <stdbool.h>
28 #include <stddef.h>
29 #include <unistd.h>
30 
31 #ifdef RIOT_VERSION
32 #include "byteorder.h"
33 #else
34 #include <arpa/inet.h>
35 #endif
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
44 #define COAP_PORT (5683)
45 
50 #define NANOCOAP_URL_MAX (64)
51 #define NANOCOAP_QS_MAX (64)
52 
58 #define COAP_OPT_URI_HOST (3)
59 #define COAP_OPT_OBSERVE (6)
60 #define COAP_OPT_URI_PATH (11)
61 #define COAP_OPT_CONTENT_FORMAT (12)
62 #define COAP_OPT_URI_QUERY (15)
63 
69 #define COAP_REQ (0)
70 #define COAP_RESP (2)
71 #define COAP_RST (3)
72 
77 #define COAP_TYPE_CON (0)
78 #define COAP_TYPE_NON (1)
79 #define COAP_TYPE_ACK (2)
80 #define COAP_TYPE_RST (3)
81 
87 #define COAP_CLASS_REQ (0)
88 #define COAP_METHOD_GET (1)
89 #define COAP_METHOD_POST (2)
90 #define COAP_METHOD_PUT (3)
91 #define COAP_METHOD_DELETE (4)
92 
98 #define COAP_GET (0x1)
99 #define COAP_POST (0x2)
100 #define COAP_PUT (0x4)
101 #define COAP_DELETE (0x8)
102 
108 #define COAP_CODE_EMPTY (0)
109 
115 #define COAP_CLASS_SUCCESS (2)
116 #define COAP_CODE_CREATED ((2 << 5) | 1)
117 #define COAP_CODE_DELETED ((2 << 5) | 2)
118 #define COAP_CODE_VALID ((2 << 5) | 3)
119 #define COAP_CODE_CHANGED ((2 << 5) | 4)
120 #define COAP_CODE_204 ((2 << 5) | 4)
121 #define COAP_CODE_CONTENT ((2 << 5) | 5)
122 #define COAP_CODE_205 ((2 << 5) | 5)
123 #define COAP_CODE_231 ((2 << 5) | 31)
124 
130 #define COAP_CLASS_CLIENT_FAILURE (4)
131 #define COAP_CODE_BAD_REQUEST ((4 << 5) | 0)
132 #define COAP_CODE_UNAUTHORIZED ((4 << 5) | 1)
133 #define COAP_CODE_BAD_OPTION ((4 << 5) | 2)
134 #define COAP_CODE_FORBIDDEN ((4 << 5) | 3)
135 #define COAP_CODE_PATH_NOT_FOUND ((4 << 5) | 4)
136 #define COAP_CODE_404 ((4 << 5) | 4)
137 #define COAP_CODE_METHOD_NOT_ALLOWED ((4 << 5) | 5)
138 #define COAP_CODE_NOT_ACCEPTABLE ((4 << 5) | 6)
139 #define COAP_CODE_PRECONDITION_FAILED ((4 << 5) | 0xC)
140 #define COAP_CODE_REQUEST_ENTITY_TOO_LARGE ((4 << 5) | 0xD)
141 #define COAP_CODE_UNSUPPORTED_CONTENT_FORMAT ((4 << 5) | 0xF)
142 
148 #define COAP_CLASS_SERVER_FAILURE (5)
149 #define COAP_CODE_INTERNAL_SERVER_ERROR ((5 << 5) | 0)
150 #define COAP_CODE_NOT_IMPLEMENTED ((5 << 5) | 1)
151 #define COAP_CODE_BAD_GATEWAY ((5 << 5) | 2)
152 #define COAP_CODE_SERVICE_UNAVAILABLE ((5 << 5) | 3)
153 #define COAP_CODE_GATEWAY_TIMEOUT ((5 << 5) | 4)
154 #define COAP_CODE_PROXYING_NOT_SUPPORTED ((5 << 5) | 5)
155 
161 #define COAP_CT_LINK_FORMAT (40)
162 #define COAP_CT_XML (41)
163 #define COAP_CT_OCTET_STREAM (42)
164 #define COAP_CT_EXI (47)
165 #define COAP_CT_JSON (50)
166 
172 #define COAP_FORMAT_TEXT (0)
173 #define COAP_FORMAT_LINK (40)
174 #define COAP_FORMAT_OCTET (42)
175 #define COAP_FORMAT_JSON (50)
176 #define COAP_FORMAT_CBOR (60)
177 
178 #define COAP_FORMAT_NONE (65535)
179 
185 #define COAP_OBS_REGISTER (0)
186 #define COAP_OBS_DEREGISTER (1)
187 
193 #define COAP_ACK_TIMEOUT (2U)
194 #define COAP_RANDOM_FACTOR (1.5)
195 #define COAP_MAX_RETRANSMIT (4)
196 #define COAP_NSTART (1)
197 #define COAP_DEFAULT_LEISURE (5)
198 
203 typedef struct {
204  uint8_t ver_t_tkl;
205  uint8_t code;
206  uint16_t id;
207  uint8_t data[];
208 } coap_hdr_t;
209 
213 typedef struct {
215  uint8_t url[NANOCOAP_URL_MAX];
216  uint8_t qs[NANOCOAP_QS_MAX];
217  uint8_t *token;
218  uint8_t *payload;
219  unsigned payload_len;
220  uint16_t content_type;
221  uint32_t observe_value;
222 } coap_pkt_t;
223 
227 typedef ssize_t (*coap_handler_t)(coap_pkt_t *pkt, uint8_t *buf, size_t len);
228 
232 typedef struct {
233  const char *path;
234  unsigned methods;
237 
241 extern const coap_resource_t coap_resources[];
242 
246 extern const unsigned coap_resources_numof;
247 
262 int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len);
263 
281 ssize_t coap_build_reply(coap_pkt_t *pkt, unsigned code,
282  uint8_t *rbuf, unsigned rlen, unsigned payload_len);
283 
305  unsigned code,
306  uint8_t *buf, size_t len,
307  unsigned ct,
308  const uint8_t *payload, uint8_t payload_len);
309 
323 ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_len);
324 
339 ssize_t coap_build_hdr(coap_hdr_t *hdr, unsigned type, uint8_t *token,
340  size_t token_len, unsigned code, uint16_t id);
341 
358 size_t coap_put_option(uint8_t *buf, uint16_t lastonum, uint16_t onum, uint8_t *odata, size_t olen);
359 
370 size_t coap_put_option_ct(uint8_t *buf, uint16_t lastonum, uint16_t content_type);
371 
383 size_t coap_put_option_uri(uint8_t *buf, uint16_t lastonum, const char *uri, uint16_t optnum);
384 
392 static inline unsigned coap_get_ver(coap_pkt_t *pkt)
393 {
394  return (pkt->hdr->ver_t_tkl & 0x60) >> 6;
395 }
396 
407 static inline unsigned coap_get_type(coap_pkt_t *pkt)
408 {
409  return (pkt->hdr->ver_t_tkl & 0x30) >> 4;
410 }
411 
419 static inline unsigned coap_get_token_len(coap_pkt_t *pkt)
420 {
421  return (pkt->hdr->ver_t_tkl & 0xf);
422 }
423 
431 static inline unsigned coap_get_code_class(coap_pkt_t *pkt)
432 {
433  return pkt->hdr->code >> 5;
434 }
435 
443 static inline unsigned coap_get_code_detail(coap_pkt_t *pkt)
444 {
445  return pkt->hdr->code & 0x1f;
446 }
447 
455 static inline unsigned coap_get_code_raw(coap_pkt_t *pkt)
456 {
457  return (unsigned)pkt->hdr->code;
458 }
459 
467 static inline unsigned coap_get_code(coap_pkt_t *pkt)
468 {
469  return (coap_get_code_class(pkt) * 100) + coap_get_code_detail(pkt);
470 }
471 
479 static inline unsigned coap_get_id(coap_pkt_t *pkt)
480 {
481  return ntohs(pkt->hdr->id);
482 }
483 
491 static inline unsigned coap_get_total_hdr_len(coap_pkt_t *pkt)
492 {
493  return sizeof(coap_hdr_t) + coap_get_token_len(pkt);
494 }
495 
504 static inline uint8_t coap_code(unsigned class, unsigned detail)
505 {
506  return (class << 5) | detail;
507 }
508 
515 static inline void coap_hdr_set_code(coap_hdr_t *hdr, uint8_t code)
516 {
517  hdr->code = code;
518 }
519 
528 static inline void coap_hdr_set_type(coap_hdr_t *hdr, unsigned type)
529 {
530  /* assert correct range of type */
531  assert(!(type & ~0x3));
532 
533  hdr->ver_t_tkl &= ~0x30;
534  hdr->ver_t_tkl |= type << 4;
535 }
536 
544 static inline unsigned coap_method2flag(unsigned code)
545 {
546  return (1 << (code - 1));
547 }
548 
557 static inline bool coap_has_observe(coap_pkt_t *pkt)
558 {
559  return pkt->observe_value != UINT32_MAX;
560 }
561 
567 static inline void coap_clear_observe(coap_pkt_t *pkt)
568 {
569  pkt->observe_value = UINT32_MAX;
570 }
571 
579 static inline uint32_t coap_get_observe(coap_pkt_t *pkt)
580 {
581  return pkt->observe_value;
582 }
583 
589  uint8_t *buf, size_t len);
590 
594 #define COAP_WELL_KNOWN_CORE_DEFAULT_HANDLER \
595  { "/.well-known/core", COAP_GET, coap_well_known_core_default_handler }
596 
597 #ifdef __cplusplus
598 }
599 #endif
600 #endif /* NET_NANOCOAP_H */
601 
static void coap_hdr_set_type(coap_hdr_t *hdr, unsigned type)
Set the message type for the given CoAP header.
Definition: nanocoap.h:528
unsigned payload_len
length of payload
Definition: nanocoap.h:219
static unsigned coap_get_code_raw(coap_pkt_t *pkt)
Get a message&#39;s raw code (class + detail)
Definition: nanocoap.h:455
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:443
const unsigned coap_resources_numof
Number of entries in global CoAP resource list.
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:431
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_well_known_core_default_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len)
Reference to the default .well-known/core handler defined by the application.
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:203
ssize_t(* coap_handler_t)(coap_pkt_t *pkt, uint8_t *buf, size_t len)
Resource handler type.
Definition: nanocoap.h:227
size_t coap_put_option_uri(uint8_t *buf, uint16_t lastonum, const char *uri, uint16_t optnum)
Insert URI encoded option into buffer.
uint8_t * token
pointer to token
Definition: nanocoap.h:217
uint8_t code
CoAP code (e.g.m 205)
Definition: nanocoap.h:205
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:232
static unsigned coap_get_total_hdr_len(coap_pkt_t *pkt)
Get the total header length (4-byte header + token length)
Definition: nanocoap.h:491
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:214
static void coap_clear_observe(coap_pkt_t *pkt)
Clears the observe option value from a packet.
Definition: nanocoap.h:567
static uint8_t coap_code(unsigned class, unsigned detail)
Encode given code class and code detail to raw code.
Definition: nanocoap.h:504
#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:515
unsigned methods
OR&#39;ed methods this resource allows.
Definition: nanocoap.h:234
static unsigned coap_get_ver(coap_pkt_t *pkt)
Get the CoAP version number.
Definition: nanocoap.h:392
const char * path
URI path of resource.
Definition: nanocoap.h:233
uint8_t ver_t_tkl
version, token, token length
Definition: nanocoap.h:204
int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len)
Parse a CoAP PDU.
uint32_t observe_value
observe value
Definition: nanocoap.h:221
static unsigned coap_get_id(coap_pkt_t *pkt)
Get the message ID of the given CoAP packet.
Definition: nanocoap.h:479
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:579
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:419
Definitions for internet operations.
uint8_t * payload
pointer to payload
Definition: nanocoap.h:218
static unsigned coap_method2flag(unsigned code)
Convert message code (request method) into a corresponding bit field.
Definition: nanocoap.h:544
uint16_t id
Req/resp ID.
Definition: nanocoap.h:206
static bool coap_has_observe(coap_pkt_t *pkt)
Identifies a packet containing an observe option.
Definition: nanocoap.h:557
coap_handler_t handler
ptr to resource handler
Definition: nanocoap.h:235
static unsigned coap_get_type(coap_pkt_t *pkt)
Get the message type.
Definition: nanocoap.h:407
static unsigned coap_get_code(coap_pkt_t *pkt)
Get a message&#39;s code in decimal format ((class * 100) + detail)
Definition: nanocoap.h:467
uint16_t content_type
content type
Definition: nanocoap.h:220
CoAP option array entry.
Definition: nanocoap.h:213
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:403