gcoap.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2015-2017 Ken Bannister. All rights reserved.
3  * SPDX-FileCopyrightText: 2017 Freie Universität Berlin
4  * SPDX-License-Identifier: LGPL-2.1-only
5  */
6 
7 #pragma once
8 
396 #include <stdint.h>
397 
398 #include "event/callback.h"
399 #include "event/timeout.h"
400 #include "net/ipv6/addr.h"
401 #include "net/sock/udp.h"
402 #if IS_USED(MODULE_GCOAP_DTLS)
403 #include "net/sock/dtls.h"
404 #endif
405 #include "net/nanocoap.h"
406 #include "net/nanocoap/cache.h"
407 #include "timex.h"
408 
409 #ifdef __cplusplus
410 extern "C" {
411 #endif
412 
422 #ifndef CONFIG_GCOAP_PORT
423 #define CONFIG_GCOAP_PORT (5683)
424 #endif
428 #ifndef CONFIG_GCOAPS_PORT
429 #define CONFIG_GCOAPS_PORT (5684)
430 #endif
431 
435 #ifndef CONFIG_GCOAP_DTLS_HANDSHAKE_TIMEOUT_MSEC
436 #define CONFIG_GCOAP_DTLS_HANDSHAKE_TIMEOUT_MSEC (3 * MS_PER_SEC)
437 #endif
438 
444 #ifndef CONFIG_GCOAP_DTLS_MINIMUM_AVAILABLE_SESSIONS
445 #define CONFIG_GCOAP_DTLS_MINIMUM_AVAILABLE_SESSIONS (1)
446 #endif
447 
452 #ifndef CONFIG_GCOAP_DTLS_MINIMUM_AVAILABLE_SESSIONS_TIMEOUT_MSEC
453 #define CONFIG_GCOAP_DTLS_MINIMUM_AVAILABLE_SESSIONS_TIMEOUT_MSEC (15 * MS_PER_SEC)
454 #endif
455 
459 #ifndef CONFIG_GCOAP_PDU_BUF_SIZE
460 #define CONFIG_GCOAP_PDU_BUF_SIZE (128)
461 #endif
462 
466 #ifndef CONFIG_GCOAP_REQ_WAITING_MAX
467 #define CONFIG_GCOAP_REQ_WAITING_MAX (2)
468 #endif
474 #define GCOAP_TOKENLEN_MAX (8)
475 
479 #define GCOAP_HEADER_MAXLEN (sizeof(coap_hdr_t) + GCOAP_TOKENLEN_MAX)
480 
487 #ifndef CONFIG_GCOAP_TOKENLEN
488 #define CONFIG_GCOAP_TOKENLEN (2)
489 #endif
490 
494 #define GCOAP_PAYLOAD_MARKER (0xFF)
495 
502 #ifndef CONFIG_GCOAP_NO_AUTO_INIT
503 #define CONFIG_GCOAP_NO_AUTO_INIT 0
504 #endif
505 
510 #define GCOAP_MEMO_UNUSED (0)
511 #define GCOAP_MEMO_RETRANSMIT (1)
512 #define GCOAP_MEMO_WAIT (2)
513 #define GCOAP_MEMO_RESP (3)
514 #define GCOAP_MEMO_TIMEOUT (4)
515 #define GCOAP_MEMO_ERR (5)
516 #define GCOAP_MEMO_RESP_TRUNC (6)
523 #define GCOAP_SEND_LIMIT_NON (-1)
524 
525 #ifdef DOXYGEN
535 #define CONFIG_GCOAP_NO_RETRANS_BACKOFF
536 #endif
537 
544 #ifndef CONFIG_GCOAP_NON_TIMEOUT_MSEC
545 #define CONFIG_GCOAP_NON_TIMEOUT_MSEC (5000U)
546 #endif
547 
556 #ifndef CONFIG_GCOAP_OBS_CLIENTS_MAX
557 #define CONFIG_GCOAP_OBS_CLIENTS_MAX (2)
558 #endif
559 
569 #ifndef CONFIG_GCOAP_OBS_NOTIFIERS_MAX
570 #define CONFIG_GCOAP_OBS_NOTIFIERS_MAX (2)
571 #endif
572 
581 #ifndef CONFIG_GCOAP_OBS_REGISTRATIONS_MAX
582 #define CONFIG_GCOAP_OBS_REGISTRATIONS_MAX (2)
583 #endif
584 
589 #define GCOAP_OBS_MEMO_UNUSED (0)
590 #define GCOAP_OBS_MEMO_IDLE (1)
591 #define GCOAP_OBS_MEMO_PENDING (2)
614 #ifndef CONFIG_GCOAP_OBS_VALUE_WIDTH
615 #define CONFIG_GCOAP_OBS_VALUE_WIDTH (3)
616 #endif
617 
621 #if (CONFIG_GCOAP_OBS_VALUE_WIDTH == 3)
622 #define GCOAP_OBS_TICK_EXPONENT (0)
623 #elif (CONFIG_GCOAP_OBS_VALUE_WIDTH == 2)
624 #define GCOAP_OBS_TICK_EXPONENT (6)
625 #elif (CONFIG_GCOAP_OBS_VALUE_WIDTH == 1)
626 #define GCOAP_OBS_TICK_EXPONENT (14)
627 #endif
628 
633 #define GCOAP_OBS_INIT_OK (0)
634 #define GCOAP_OBS_INIT_ERR (-1)
635 #define GCOAP_OBS_INIT_UNUSED (-2)
642 #ifndef GCOAP_DTLS_EXTRA_STACKSIZE
643 #if IS_USED(MODULE_GCOAP_DTLS)
644 #define GCOAP_DTLS_EXTRA_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
645 #else
646 #define GCOAP_DTLS_EXTRA_STACKSIZE (0)
647 #endif
648 #endif
649 
653 #if IS_USED(MODULE_GCOAP_FILESERVER)
654 #include "vfs.h"
655 #define GCOAP_VFS_EXTRA_STACKSIZE (VFS_DIR_BUFFER_SIZE + VFS_FILE_BUFFER_SIZE)
656 #else
657 #define GCOAP_VFS_EXTRA_STACKSIZE (0)
658 #endif
659 
660 #ifndef GCOAP_STACK_SIZE
661 #define GCOAP_STACK_SIZE (THREAD_STACKSIZE_DEFAULT + DEBUG_EXTRA_STACKSIZE \
662  + sizeof(coap_pkt_t) + GCOAP_DTLS_EXTRA_STACKSIZE \
663  + GCOAP_VFS_EXTRA_STACKSIZE)
664 #endif
671 #ifndef CONFIG_GCOAP_RESEND_BUFS_MAX
672 #define CONFIG_GCOAP_RESEND_BUFS_MAX (1)
673 #endif
674 
680 #define COAP_LINK_FLAG_INIT_RESLIST (1)
688 typedef struct {
689  unsigned content_format;
690  size_t link_pos;
691  uint16_t flags;
694 
706 typedef ssize_t (*gcoap_link_encoder_t)(const coap_resource_t *resource, char *buf,
707  size_t maxlen, coap_link_encoder_ctx_t *context);
708 
713 #define GCOAP_RESOURCE_FOUND (0)
714 #define GCOAP_RESOURCE_WRONG_METHOD (1)
715 #define GCOAP_RESOURCE_NO_PATH (2)
716 #define GCOAP_RESOURCE_ERROR (3)
722 typedef struct gcoap_listener gcoap_listener_t;
723 
736 typedef int (*gcoap_request_matcher_t)(gcoap_listener_t *listener,
737  const coap_resource_t **resource,
738  coap_pkt_t *pdu);
739 
746 typedef enum {
751 
755 typedef struct {
757  union {
758  sock_udp_t *udp;
759 #if IS_USED(MODULE_GCOAP_DTLS) || defined(DOXYGEN)
760  sock_dtls_t *dtls;
761 #endif
762  } socket;
763 #if IS_USED(MODULE_GCOAP_DTLS) || defined(DOXYGEN)
767 #endif
769 
775  size_t resources_len;
800 };
801 
806 
813 typedef void (*gcoap_resp_handler_t)(const gcoap_request_memo_t *memo,
814  coap_pkt_t* pdu,
815  const sock_udp_ep_t *remote);
816 
820 typedef struct {
821  uint8_t *pdu_buf;
822  size_t pdu_len;
824 
829  unsigned state;
832  union {
836  } msg;
840  void *context;
844 #if IS_USED(MODULE_NANOCOAP_CACHE) || DOXYGEN
851 #endif
852 };
853 
857 typedef struct {
861  uint8_t token[GCOAP_TOKENLEN_MAX];
862  uint16_t last_msgid;
863  unsigned token_len;
866 
877 
894 
908  const coap_resource_t *last_resource,
909  const char *uri_path);
910 
937 int gcoap_req_init_path_buffer(coap_pkt_t *pdu, uint8_t *buf, size_t len,
938  unsigned code, const char *path,
939  size_t path_len);
940 
965 static inline int gcoap_req_init(coap_pkt_t *pdu, uint8_t *buf, size_t len,
966  unsigned code, const char *path)
967 {
968  return gcoap_req_init_path_buffer(pdu, buf, len, code, path,
969  (path) ? strlen(path) : 0U);
970 }
971 
984 static inline ssize_t gcoap_request(coap_pkt_t *pdu, uint8_t *buf, size_t len,
985  unsigned code, char *path)
986 {
987  if (gcoap_req_init(pdu, buf, len, code, path) == 0) {
988  if (IS_USED(MODULE_NANOCOAP_CACHE)) {
989  /* remove ETag option slack added for cache validation */
990  coap_opt_remove(pdu, COAP_OPT_ETAG);
991  }
993  }
994  return -1;
995 }
996 
1019 ssize_t gcoap_req_send(const uint8_t *buf, size_t len,
1020  const sock_udp_ep_t *remote, const sock_udp_ep_t *local,
1021  gcoap_resp_handler_t resp_handler, void *context,
1022  gcoap_socket_type_t tl_type);
1023 
1037 int gcoap_resp_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, unsigned code);
1038 
1050 static inline ssize_t gcoap_response(coap_pkt_t *pdu, uint8_t *buf,
1051  size_t len, unsigned code)
1052 {
1053  return (gcoap_resp_init(pdu, buf, len, code) == 0)
1055  : -1;
1056 }
1057 
1076 int gcoap_obs_init(coap_pkt_t *pdu, uint8_t *buf, size_t len,
1077  const coap_resource_t *resource);
1078 
1092 size_t gcoap_obs_send(const uint8_t *buf, size_t len,
1093  const coap_resource_t *resource);
1094 
1123 int gcoap_obs_req_forget(const sock_udp_ep_t *remote, const uint8_t *token,
1124  size_t tokenlen);
1125 
1133 uint8_t gcoap_op_state(void);
1134 
1157 int gcoap_get_resource_list(void *buf, size_t maxlen, uint8_t cf,
1158  gcoap_socket_type_t tl_type);
1159 
1173 ssize_t gcoap_encode_link(const coap_resource_t *resource, char *buf,
1174  size_t maxlen, coap_link_encoder_ctx_t *context);
1175 
1176 #if IS_USED(MODULE_GCOAP_DTLS) || defined(DOXYGEN)
1185 #endif
1186 
1195 {
1196  if (memo->send_limit == GCOAP_SEND_LIMIT_NON) {
1197  return (coap_hdr_t *)&memo->msg.hdr_buf[0];
1198  }
1199  else {
1200  return (coap_hdr_t *)memo->msg.data.pdu_buf;
1201  }
1202 }
1203 
1204 #ifdef __cplusplus
1205 }
1206 #endif
1207 
Provides a callback-with-argument event type.
int16_t kernel_pid_t
Unique process identifier.
Definition: sched.h:135
int gcoap_req_init_path_buffer(coap_pkt_t *pdu, uint8_t *buf, size_t len, unsigned code, const char *path, size_t path_len)
Initializes a CoAP request PDU on a buffer.
int gcoap_get_resource_list(void *buf, size_t maxlen, uint8_t cf, gcoap_socket_type_t tl_type)
Get the resource list, currently only CoRE Link Format (COAP_FORMAT_LINK) supported.
int gcoap_resp_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, unsigned code)
Initializes a CoAP response packet on a buffer.
ssize_t(* gcoap_link_encoder_t)(const coap_resource_t *resource, char *buf, size_t maxlen, coap_link_encoder_ctx_t *context)
Handler function to write a resource link.
Definition: gcoap.h:706
void gcoap_register_listener(gcoap_listener_t *listener)
Starts listening for resource paths.
static int gcoap_req_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, unsigned code, const char *path)
Initializes a CoAP request PDU on a buffer.
Definition: gcoap.h:965
#define GCOAP_TOKENLEN_MAX
Maximum length in bytes for a token.
Definition: gcoap.h:474
gcoap_socket_type_t
CoAP socket types.
Definition: gcoap.h:746
int gcoap_obs_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, const coap_resource_t *resource)
Initializes a CoAP Observe notification packet on a buffer, for the observer registered for a resourc...
ssize_t gcoap_req_send(const uint8_t *buf, size_t len, const sock_udp_ep_t *remote, const sock_udp_ep_t *local, gcoap_resp_handler_t resp_handler, void *context, gcoap_socket_type_t tl_type)
Sends a buffer containing a CoAP request to the provided endpoint.
sock_dtls_t * gcoap_get_sock_dtls(void)
Get the underlying DTLS socket of gcoap.
#define GCOAP_HEADER_MAXLEN
Maximum length in bytes for a header, including the token.
Definition: gcoap.h:479
const coap_resource_t * gcoap_get_resource_by_path_iterator(const gcoap_listener_t **last_listener, const coap_resource_t *last_resource, const char *uri_path)
Iterate through all registered listeners and check for a resource, matching by uri_path.
void(* gcoap_resp_handler_t)(const gcoap_request_memo_t *memo, coap_pkt_t *pdu, const sock_udp_ep_t *remote)
Handler function for a server response, including the state for the originating request.
Definition: gcoap.h:813
#define GCOAP_SEND_LIMIT_NON
Value for send_limit in request memo when non-confirmable type.
Definition: gcoap.h:523
ssize_t gcoap_encode_link(const coap_resource_t *resource, char *buf, size_t maxlen, coap_link_encoder_ctx_t *context)
Writes a resource in CoRE Link Format to a provided buffer.
size_t gcoap_obs_send(const uint8_t *buf, size_t len, const coap_resource_t *resource)
Sends a buffer containing a CoAP Observe notification to the observer registered for a resource.
int gcoap_obs_req_forget(const sock_udp_ep_t *remote, const uint8_t *token, size_t tokenlen)
Forgets (invalidates) an existing observe request.
static ssize_t gcoap_response(coap_pkt_t *pdu, uint8_t *buf, size_t len, unsigned code)
Writes a complete CoAP response PDU when there is no payload.
Definition: gcoap.h:1050
int(* gcoap_request_matcher_t)(gcoap_listener_t *listener, const coap_resource_t **resource, coap_pkt_t *pdu)
Handler function for the request matcher strategy.
Definition: gcoap.h:736
kernel_pid_t gcoap_init(void)
Initializes the gcoap thread and device.
uint8_t gcoap_op_state(void)
Provides important operational statistics.
static coap_hdr_t * gcoap_request_memo_get_hdr(const gcoap_request_memo_t *memo)
Get the header of a request from a gcoap_request_memo_t.
Definition: gcoap.h:1194
static ssize_t gcoap_request(coap_pkt_t *pdu, uint8_t *buf, size_t len, unsigned code, char *path)
Writes a complete CoAP request PDU when there is not a payload.
Definition: gcoap.h:984
@ GCOAP_SOCKET_TYPE_UDP
Unencrypted UDP transport.
Definition: gcoap.h:748
@ GCOAP_SOCKET_TYPE_UNDEF
undefined
Definition: gcoap.h:747
@ GCOAP_SOCKET_TYPE_DTLS
DTLS-over-UDP transport.
Definition: gcoap.h:749
#define CONFIG_NANOCOAP_CACHE_KEY_LENGTH
The length of the cache key in bytes.
Definition: cache.h:44
#define COAP_OPT_FINISH_NONE
no special handling required
Definition: nanocoap.h:179
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.
ssize_t coap_opt_finish(coap_pkt_t *pkt, uint16_t flags)
Finalizes options as required and prepares for payload.
int socket(int domain, int type, int protocol)
Create an endpoint for communication.
Definitions for IPv6 addresses.
#define IS_USED(module)
Checks whether a module is being used or not.
Definition: modules.h:67
nanocoap-cache API
nanocoap API
DTLS sock definitions.
UDP sock definitions.
Common IP-based transport layer end point.
Definition: sock.h:211
Raw CoAP PDU header structure.
Definition: nanocoap.h:187
CoAP PDU parsing context structure.
Definition: nanocoap.h:218
Type for CoAP resource entry.
Definition: nanocoap.h:297
Callback Event structure definition.
Definition: callback.h:45
Timeout Event structure.
Definition: timeout.h:46
A modular collection of resources for a server.
Definition: gcoap.h:773
gcoap_link_encoder_t link_encoder
Writes a link for a resource.
Definition: gcoap.h:786
struct gcoap_listener * next
Next listener in list.
Definition: gcoap.h:787
size_t resources_len
Length of array.
Definition: gcoap.h:775
gcoap_socket_type_t tl_type
Transport type for the listener.
Definition: gcoap.h:785
const coap_resource_t * resources
First element in the array of resources.
Definition: gcoap.h:774
gcoap_request_matcher_t request_matcher
Function that picks a suitable request handler from a request.
Definition: gcoap.h:799
Memo for Observe registration and notifications.
Definition: gcoap.h:857
unsigned token_len
Actual length of token attribute.
Definition: gcoap.h:863
gcoap_socket_t socket
Transport type to observer.
Definition: gcoap.h:864
const coap_resource_t * resource
Entity being observed.
Definition: gcoap.h:860
sock_udp_ep_t * notifier
Local endpoint to send notifications.
Definition: gcoap.h:859
uint16_t last_msgid
Message ID of last notification.
Definition: gcoap.h:862
sock_udp_ep_t * observer
Client endpoint; unused if null.
Definition: gcoap.h:858
Memo to handle a response for a request.
Definition: gcoap.h:828
void * context
ptr to user defined context data
Definition: gcoap.h:840
gcoap_resp_handler_t resp_handler
Callback for the response.
Definition: gcoap.h:839
event_callback_t resp_tmout_cb
Callback for response timeout.
Definition: gcoap.h:842
unsigned state
State of this memo, a GCOAP_MEMO...
Definition: gcoap.h:829
int send_limit
Remaining resends, 0 if none; GCOAP_SEND_LIMIT_NON if non-confirmable.
Definition: gcoap.h:830
gcoap_resend_t data
Endpoint and PDU buffer, for resend.
Definition: gcoap.h:835
uint8_t cache_key[CONFIG_NANOCOAP_CACHE_KEY_LENGTH]
Cache key for the request.
Definition: gcoap.h:850
union gcoap_request_memo::@361 msg
Request message data; if confirmable, supports resending message.
sock_udp_ep_t remote_ep
Remote endpoint.
Definition: gcoap.h:838
gcoap_socket_t socket
Transport type to remote endpoint.
Definition: gcoap.h:843
uint8_t hdr_buf[GCOAP_HEADER_MAXLEN]
Copy of PDU header, if no resends.
Definition: gcoap.h:833
event_timeout_t resp_evt_tmout
Limits wait for response.
Definition: gcoap.h:841
Extends request memo for resending a confirmable request.
Definition: gcoap.h:820
uint8_t * pdu_buf
Buffer containing the PDU.
Definition: gcoap.h:821
size_t pdu_len
Length of pdu_buf.
Definition: gcoap.h:822
CoAP socket to handle multiple transport types.
Definition: gcoap.h:755
gcoap_socket_type_t type
Type of stored socket.
Definition: gcoap.h:756
sock_dtls_session_t ctx_dtls_session
Session object for the stored socket.
Definition: gcoap.h:764
Information about remote client connected to the server.
Information about DTLS sock.
UDP sock type.
Definition: sock_types.h:128
Provides functionality to trigger events after timeout.
Utility library for comparing and computing timestamps.