nanocoap.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016-17 Kaspar Schleiser <kaspar@schleiser.de>
3  * 2018 Freie Universit├Ąt Berlin
4  * 2018 Ken Bannister <kb2ma@runbox.com>
5  *
6  * This file is subject to the terms and conditions of the GNU Lesser
7  * General Public License v2.1. See the file LICENSE in the top level
8  * directory for more details.
9  */
10 
144 #ifndef NET_NANOCOAP_H
145 #define NET_NANOCOAP_H
146 
147 #include <assert.h>
148 #include <stdint.h>
149 #include <stdbool.h>
150 #include <stddef.h>
151 #include <unistd.h>
152 
153 #ifdef RIOT_VERSION
154 #include "byteorder.h"
155 #include "net/coap.h"
156 #else
157 #include "coap.h"
158 #include <arpa/inet.h>
159 #endif
160 
161 #ifdef __cplusplus
162 extern "C" {
163 #endif
164 
169 #define COAP_GET (0x1)
170 #define COAP_POST (0x2)
171 #define COAP_PUT (0x4)
172 #define COAP_DELETE (0x8)
173 
178 #define COAP_FORMAT_NONE (UINT16_MAX)
179 
184 #define NANOCOAP_NOPTS_MAX (16)
185 #define NANOCOAP_URI_MAX (64)
186 #define NANOCOAP_BLOCK_SIZE_EXP_MAX (6)
190 #ifdef MODULE_GCOAP
191 #define NANOCOAP_URL_MAX NANOCOAP_URI_MAX
192 #define NANOCOAP_QS_MAX (64)
193 #endif
194 
202 #define COAP_OPT_FINISH_NONE (0x0000)
204 #define COAP_OPT_FINISH_PAYLOAD (0x0001)
210 typedef struct __attribute__((packed)) {
211  uint8_t ver_t_tkl;
212  uint8_t code;
213  uint16_t id;
215 
219 typedef struct {
220  uint16_t opt_num;
221  uint16_t offset;
223 
227 typedef struct {
228  coap_hdr_t *hdr;
229  uint8_t *token;
230  uint8_t *payload;
231  uint16_t payload_len;
232  uint16_t options_len;
233  coap_optpos_t options[NANOCOAP_NOPTS_MAX];
234 #ifdef MODULE_GCOAP
235  uint32_t observe_value;
236 #endif
237 } coap_pkt_t;
238 
242 typedef ssize_t (*coap_handler_t)(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context);
247 typedef struct {
248  const char *path;
249  unsigned methods;
250  coap_handler_t handler;
251  void *context;
253 
257 typedef struct {
258  size_t offset;
259  uint32_t blknum;
260  unsigned szx;
261  int more;
263 } coap_block1_t;
264 
268 typedef struct {
269  size_t start;
270  size_t end;
271  size_t cur;
272  uint8_t *opt;
274 
278 extern const coap_resource_t coap_resources[];
279 
283 extern const unsigned coap_resources_numof;
284 
299 int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len);
300 
318 ssize_t coap_build_reply(coap_pkt_t *pkt, unsigned code,
319  uint8_t *rbuf, unsigned rlen, unsigned payload_len);
320 
342  unsigned code,
343  uint8_t *buf, size_t len,
344  unsigned ct,
345  const uint8_t *payload, uint8_t payload_len);
346 
360 ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_len);
361 
376 ssize_t coap_build_hdr(coap_hdr_t *hdr, unsigned type, uint8_t *token,
377  size_t token_len, unsigned code, uint16_t id);
378 
393 void coap_pkt_init(coap_pkt_t *pkt, uint8_t *buf, size_t len, size_t header_len);
394 
411 size_t coap_put_option(uint8_t *buf, uint16_t lastonum, uint16_t onum, uint8_t *odata, size_t olen);
412 
423 size_t coap_put_option_ct(uint8_t *buf, uint16_t lastonum, uint16_t content_type);
424 
437 size_t coap_opt_put_string(uint8_t *buf, uint16_t lastonum, uint16_t optnum,
438  const char *string, char separator);
439 
450 static inline size_t coap_opt_put_uri_path(uint8_t *buf, uint16_t lastonum,
451  const char *uri)
452 {
453  return coap_opt_put_string(buf, lastonum, COAP_OPT_URI_PATH, uri, '/');
454 }
455 
466 static inline size_t coap_opt_put_uri_query(uint8_t *buf, uint16_t lastonum,
467  const char *uri)
468 {
469  return coap_opt_put_string(buf, lastonum, COAP_OPT_URI_QUERY, uri, '&');
470 }
471 
482 static inline size_t coap_opt_put_location_path(uint8_t *buf,
483  uint16_t lastonum,
484  const char *location)
485 {
486  return coap_opt_put_string(buf, lastonum, COAP_OPT_LOCATION_PATH,
487  location, '/');
488 }
489 
500 static inline size_t coap_opt_put_location_query(uint8_t *buf,
501  uint16_t lastonum,
502  const char *location)
503 {
504  return coap_opt_put_string(buf, lastonum, COAP_OPT_LOCATION_QUERY,
505  location, '&');
506 }
507 
520 int coap_get_blockopt(coap_pkt_t *pkt, uint16_t option, uint32_t *blknum, unsigned *szx);
521 
539 int coap_get_block1(coap_pkt_t *pkt, coap_block1_t *block1);
540 
550 int coap_get_block2(coap_pkt_t *pkt, coap_block1_t *block2);
551 
564 size_t coap_put_option_block1(uint8_t *buf, uint16_t lastonum, unsigned blknum, unsigned szx, int more);
565 
583 size_t coap_put_block1_ok(uint8_t *pkt_pos, coap_block1_t *block1, uint16_t lastonum);
584 
601 ssize_t coap_opt_add_string(coap_pkt_t *pkt, uint16_t optnum, const char *string, char separator);
602 
616 ssize_t coap_opt_add_uint(coap_pkt_t *pkt, uint16_t optnum, uint32_t value);
617 
629 ssize_t coap_opt_finish(coap_pkt_t *pkt, uint16_t flags);
630 
646 size_t coap_opt_put_block2(uint8_t *buf, uint16_t lastonum, coap_block_slicer_t *slicer, bool more);
647 
656 unsigned coap_get_content_type(coap_pkt_t *pkt);
657 
675 ssize_t coap_opt_get_string(const coap_pkt_t *pkt, uint16_t optnum,
676  uint8_t *target, size_t max_len, char separator);
677 
692 static inline ssize_t coap_get_uri_path(const coap_pkt_t *pkt, uint8_t *target)
693 {
694  return coap_opt_get_string(pkt, COAP_OPT_URI_PATH, target,
695  NANOCOAP_URI_MAX, '/');
696 }
697 
712 static inline ssize_t coap_get_uri_query(const coap_pkt_t *pkt, uint8_t *target)
713 {
714  return coap_opt_get_string(pkt, COAP_OPT_URI_QUERY, target,
715  NANOCOAP_URI_MAX, '&');
716 }
717 
733 static inline ssize_t coap_get_location_path(const coap_pkt_t *pkt,
734  uint8_t *target, size_t max_len)
735 {
736  return coap_opt_get_string(pkt, COAP_OPT_LOCATION_PATH,
737  target, max_len, '/');
738 }
739 
755 static inline ssize_t coap_get_location_query(const coap_pkt_t *pkt,
756  uint8_t *target, size_t max_len)
757 {
758  return coap_opt_get_string(pkt, COAP_OPT_LOCATION_QUERY,
759  target, max_len, '&');
760 }
761 
772 
785 
803 ssize_t coap_block2_build_reply(coap_pkt_t *pkt, unsigned code,
804  uint8_t *rbuf, unsigned rlen, unsigned payload_len,
805  coap_block_slicer_t *slicer);
806 
820 size_t coap_blockwise_put_char(coap_block_slicer_t *slicer, uint8_t *bufpos, char c);
821 
836 size_t coap_blockwise_put_bytes(coap_block_slicer_t *slicer, uint8_t *bufpos,
837  const uint8_t *c, size_t len);
838 
846 static inline unsigned coap_szx2size(unsigned szx)
847 {
848  return (1 << (szx + 4));
849 }
850 
858 static inline unsigned coap_get_ver(coap_pkt_t *pkt)
859 {
860  return (pkt->hdr->ver_t_tkl & 0x60) >> 6;
861 }
862 
873 static inline unsigned coap_get_type(coap_pkt_t *pkt)
874 {
875  return (pkt->hdr->ver_t_tkl & 0x30) >> 4;
876 }
877 
885 static inline unsigned coap_get_token_len(coap_pkt_t *pkt)
886 {
887  return (pkt->hdr->ver_t_tkl & 0xf);
888 }
889 
897 static inline unsigned coap_get_code_class(coap_pkt_t *pkt)
898 {
899  return pkt->hdr->code >> 5;
900 }
901 
909 static inline unsigned coap_get_code_detail(coap_pkt_t *pkt)
910 {
911  return pkt->hdr->code & 0x1f;
912 }
913 
921 static inline unsigned coap_get_code_raw(coap_pkt_t *pkt)
922 {
923  return (unsigned)pkt->hdr->code;
924 }
925 
933 static inline unsigned coap_get_code(coap_pkt_t *pkt)
934 {
935  return (coap_get_code_class(pkt) * 100) + coap_get_code_detail(pkt);
936 }
937 
945 static inline unsigned coap_get_id(coap_pkt_t *pkt)
946 {
947  return ntohs(pkt->hdr->id);
948 }
949 
957 static inline uint8_t *coap_hdr_data_ptr(coap_hdr_t *hdr)
958 {
959  return ((uint8_t *)hdr) + sizeof(coap_hdr_t);
960 }
961 
969 static inline unsigned coap_get_total_hdr_len(coap_pkt_t *pkt)
970 {
971  return sizeof(coap_hdr_t) + coap_get_token_len(pkt);
972 }
973 
982 static inline uint8_t coap_code(unsigned cls, unsigned detail)
983 {
984  return (cls << 5) | detail;
985 }
986 
993 static inline void coap_hdr_set_code(coap_hdr_t *hdr, uint8_t code)
994 {
995  hdr->code = code;
996 }
997 
1006 static inline void coap_hdr_set_type(coap_hdr_t *hdr, unsigned type)
1008  /* assert correct range of type */
1009  assert(!(type & ~0x3));
1010 
1011  hdr->ver_t_tkl &= ~0x30;
1012  hdr->ver_t_tkl |= type << 4;
1013 }
1014 
1022 static inline unsigned coap_method2flag(unsigned code)
1024  return (1 << (code - 1));
1025 }
1026 
1027 #if defined(MODULE_GCOAP) || defined(DOXYGEN)
1028 
1036 static inline bool coap_has_observe(coap_pkt_t *pkt)
1038  return pkt->observe_value != UINT32_MAX;
1039 }
1040 
1046 static inline void coap_clear_observe(coap_pkt_t *pkt)
1048  pkt->observe_value = UINT32_MAX;
1049 }
1050 
1058 static inline uint32_t coap_get_observe(coap_pkt_t *pkt)
1060  return pkt->observe_value;
1061 }
1062 #endif
1063 
1069  uint8_t *buf, size_t len,
1070  void *context);
1071 
1075 #define COAP_WELL_KNOWN_CORE_DEFAULT_HANDLER \
1076  { \
1077  .path = "/.well-known/core", \
1078  .methods = COAP_GET, \
1079  .handler = coap_well_known_core_default_handler \
1080  }
1081 
1082 #ifdef __cplusplus
1083 }
1084 #endif
1085 #endif /* NET_NANOCOAP_H */
1086 
static void coap_hdr_set_type(coap_hdr_t *hdr, unsigned type)
Set the message type for the given CoAP header.
Definition: nanocoap.h:1007
static unsigned coap_get_code_raw(coap_pkt_t *pkt)
Get a message&#39;s raw code (class + detail)
Definition: nanocoap.h:922
size_t coap_blockwise_put_bytes(coap_block_slicer_t *slicer, uint8_t *bufpos, const uint8_t *c, size_t len)
Add a byte array to a block2 reply.
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:910
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.
size_t coap_opt_put_block2(uint8_t *buf, uint16_t lastonum, coap_block_slicer_t *slicer, bool more)
Insert block2 option into buffer.
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:898
size_t coap_put_option_ct(uint8_t *buf, uint16_t lastonum, uint16_t content_type)
Insert content type option into buffer.
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:451
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:501
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:211
static unsigned coap_szx2size(unsigned szx)
Helper to decode SZX value to size in bytes.
Definition: nanocoap.h:847
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.
CoAP option array entry.
Definition: nanocoap.h:220
static ssize_t coap_get_uri_query(const coap_pkt_t *pkt, uint8_t *target)
Convenience function for getting the packet&#39;s URI_QUERY option.
Definition: nanocoap.h:713
Blockwise transfer helper struct.
Definition: nanocoap.h:269
uint8_t code
CoAP code (e.g.m 205)
Definition: nanocoap.h:213
static ssize_t coap_get_location_path(const coap_pkt_t *pkt, uint8_t *target, size_t max_len)
Convenience function for getting the packet&#39;s LOCATION_PATH option.
Definition: nanocoap.h:734
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.
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:483
Type for CoAP resource entry.
Definition: nanocoap.h:248
static unsigned coap_get_total_hdr_len(coap_pkt_t *pkt)
Get the total header length (4-byte header + token length)
Definition: nanocoap.h:970
ssize_t coap_opt_get_string(const 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.
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:229
static void coap_clear_observe(coap_pkt_t *pkt)
Clears the observe option value from a packet.
Definition: nanocoap.h:1047
unsigned coap_get_content_type(coap_pkt_t *pkt)
Get content type from packet.
unistd.h wrapper for MSP430
#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:994
ssize_t coap_opt_finish(coap_pkt_t *pkt, uint16_t flags)
Finalizes options as required and prepares for payload.
static unsigned coap_get_ver(coap_pkt_t *pkt)
Get the CoAP version number.
Definition: nanocoap.h:859
uint8_t ver_t_tkl
version, token, token length
Definition: nanocoap.h:212
Block1 helper struct.
Definition: nanocoap.h:258
static uint8_t coap_code(unsigned cls, unsigned detail)
Encode given code class and code detail to raw code.
Definition: nanocoap.h:983
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.
int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len)
Parse a CoAP PDU.
void coap_block2_init(coap_pkt_t *pkt, coap_block_slicer_t *slicer)
Initialize a block2 slicer struct for writing the payload.
static unsigned coap_get_id(coap_pkt_t *pkt)
Get the message ID of the given CoAP packet.
Definition: nanocoap.h:946
int coap_get_block2(coap_pkt_t *pkt, coap_block1_t *block2)
Block2 option getter.
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:1059
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:467
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:886
void coap_block2_finish(coap_block_slicer_t *slicer)
Finish a block2 response.
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)
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.
static unsigned coap_method2flag(unsigned code)
Convert message code (request method) into a corresponding bit field.
Definition: nanocoap.h:1023
static ssize_t coap_get_uri_path(const coap_pkt_t *pkt, uint8_t *target)
Convenience function for getting the packet&#39;s URI_PATH.
Definition: nanocoap.h:693
ssize_t coap_opt_add_uint(coap_pkt_t *pkt, uint16_t optnum, uint32_t value)
Encode the given uint option into pkt.
static uint8_t * coap_hdr_data_ptr(coap_hdr_t *hdr)
Get the start of data after the header.
Definition: nanocoap.h:958
uint16_t id
Req/resp ID.
Definition: nanocoap.h:214
static bool coap_has_observe(coap_pkt_t *pkt)
Identifies a packet containing an observe option.
Definition: nanocoap.h:1037
size_t coap_blockwise_put_char(coap_block_slicer_t *slicer, uint8_t *bufpos, char c)
Add a single character to a block2 reply.
Generic CoAP values as defined by RFC7252.
static unsigned coap_get_type(coap_pkt_t *pkt)
Get the message type.
Definition: nanocoap.h:874
ssize_t(* coap_handler_t)(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context)
Resource handler type.
Definition: nanocoap.h:243
static unsigned coap_get_code(coap_pkt_t *pkt)
Get a message&#39;s code in decimal format ((class * 100) + detail)
Definition: nanocoap.h:934
CoAP PDU parsing context structure.
Definition: nanocoap.h:228
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.
static ssize_t coap_get_location_query(const coap_pkt_t *pkt, uint8_t *target, size_t max_len)
Convenience function for getting the packet&#39;s LOCATION_QUERY option.
Definition: nanocoap.h:756
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