diff --git a/include/coap3/coap_net.h b/include/coap3/coap_net.h
index ebb650aa8e..ce292ec3de 100644
--- a/include/coap3/coap_net.h
+++ b/include/coap3/coap_net.h
@@ -37,6 +37,7 @@
#include "coap_pdu.h"
#include "coap_session.h"
#include "coap_debug.h"
+#include "coap_resource.h"
/**
* @ingroup application_api
@@ -607,6 +608,28 @@ void coap_context_set_app_data(coap_context_t *context, void *data);
*/
void *coap_context_get_app_data(const coap_context_t *context);
+/**
+ * Definition of get .well-known/core string callback function
+ */
+typedef coap_print_status_t (*coap_print_wellknown_t)(coap_context_t *context,
+ coap_session_t *session,
+ const coap_pdu_t *request,
+ unsigned char *buf,
+ size_t *buflen,
+ size_t offset,
+ const coap_string_t *query_filter);
+
+/**
+ * Defines the callback that is called when the .well-known/core resource is requested.
+ *
+ * @param context The context to associate the print_wellknown callback with
+ * @param callback The callback to invoke when the .well-known/core resource is requested
+ * or NULL to unregister a previously registered callback.
+ *
+ */
+void coap_register_print_wellknown_callback(coap_context_t *context,
+ coap_print_wellknown_t callback);
+
/**@}*/
/**
diff --git a/include/coap3/coap_net_internal.h b/include/coap3/coap_net_internal.h
index 0c0b28547f..6646ce95f3 100644
--- a/include/coap3/coap_net_internal.h
+++ b/include/coap3/coap_net_internal.h
@@ -59,6 +59,8 @@ struct coap_context_t {
coap_resource_release_userdata_handler_t release_userdata;
/**< function to release user_data
when resource is deleted */
+ coap_print_wellknown_t print_wellknown_userdata; /**< custom response for
+ well-known/core resource */
#endif /* COAP_SERVER_SUPPORT */
#if COAP_ASYNC_SUPPORT
diff --git a/include/coap3/coap_resource.h b/include/coap3/coap_resource.h
index 395fb9ef48..30d463c560 100644
--- a/include/coap3/coap_resource.h
+++ b/include/coap3/coap_resource.h
@@ -494,6 +494,33 @@ coap_print_status_t coap_print_link(const coap_resource_t *resource,
size_t *len,
size_t *offset);
+/**
+ * Prints the names of all known resources for @p context to @p buf. This function
+ * sets @p buflen to the number of bytes actually written and returns
+ * @c 1 on success. On error, the value in @p buflen is undefined and
+ * the return value will be @c 0.
+ *
+ * @param context The context with the resource map.
+ * @param buf The buffer to write the result.
+ * @param buflen Must be initialized to the maximum length of @p buf and will be
+ * set to the length of the well-known response on return.
+ * @param offset The offset in bytes where the output shall start and is
+ * shifted accordingly with the characters that have been
+ * processed. This parameter is used to support the block
+ * option.
+ * @param query_filter A filter query according to Link Format
+ *
+ * @return COAP_PRINT_STATUS_ERROR on error. Otherwise, the lower 28 bits are
+ * set to the number of bytes that have actually been written to
+ * @p buf. COAP_PRINT_STATUS_TRUNC is set when the output has been
+ * truncated.
+ */
+COAP_API coap_print_status_t coap_print_wellknown(coap_context_t *context,
+ unsigned char *buf,
+ size_t *buflen,
+ size_t offset,
+ const coap_string_t *query_filter);
+
/** @} */
/**
diff --git a/include/coap3/coap_resource_internal.h b/include/coap3/coap_resource_internal.h
index 40811504b9..6bb5a49eb3 100644
--- a/include/coap3/coap_resource_internal.h
+++ b/include/coap3/coap_resource_internal.h
@@ -182,10 +182,32 @@ coap_resource_t *coap_get_resource_from_uri_path_lkd(coap_context_t *context,
*/
void coap_delete_attr(coap_attr_t *attr);
-coap_print_status_t coap_print_wellknown(coap_context_t *,
- unsigned char *,
- size_t *, size_t,
- const coap_string_t *);
+/**
+ * Prints the names of all known resources for @p context to @p buf. This function
+ * sets @p buflen to the number of bytes actually written and returns
+ * @c 1 on success. On error, the value in @p buflen is undefined and
+ * the return value will be @c 0.
+ *
+ * @param context The context with the resource map.
+ * @param buf The buffer to write the result.
+ * @param buflen Must be initialized to the maximum length of @p buf and will be
+ * set to the length of the well-known response on return.
+ * @param offset The offset in bytes where the output shall start and is
+ * shifted accordingly with the characters that have been
+ * processed. This parameter is used to support the block
+ * option.
+ * @param query_filter A filter query according to Link Format
+ *
+ * @return COAP_PRINT_STATUS_ERROR on error. Otherwise, the lower 28 bits are
+ * set to the number of bytes that have actually been written to
+ * @p buf. COAP_PRINT_STATUS_TRUNC is set when the output has been
+ * truncated.
+ */
+coap_print_status_t coap_print_wellknown_lkd(coap_context_t *context,
+ unsigned char *buf,
+ size_t *buflen,
+ size_t offset,
+ const coap_string_t *query_filter);
/** @} */
diff --git a/libcoap-3.map b/libcoap-3.map
index c5dc03d5f2..502cc2e3b4 100644
--- a/libcoap-3.map
+++ b/libcoap-3.map
@@ -190,6 +190,7 @@ global:
coap_print_addr;
coap_print_ip_addr;
coap_print_link;
+ coap_print_wellknown;
coap_prng;
coap_prng_init;
coap_q_block_is_supported;
@@ -201,6 +202,7 @@ global:
coap_register_option;
coap_register_ping_handler;
coap_register_pong_handler;
+ coap_register_print_wellknown_callback;
coap_register_request_handler;
coap_register_response_handler;
coap_resize_binary;
diff --git a/libcoap-3.sym b/libcoap-3.sym
index 348e82a43c..efee3edd0d 100644
--- a/libcoap-3.sym
+++ b/libcoap-3.sym
@@ -188,6 +188,7 @@ coap_persist_track_funcs
coap_print_addr
coap_print_ip_addr
coap_print_link
+coap_print_wellknown
coap_prng
coap_prng_init
coap_q_block_is_supported
@@ -199,6 +200,7 @@ coap_register_nack_handler
coap_register_option
coap_register_ping_handler
coap_register_pong_handler
+coap_register_print_wellknown_callback
coap_register_request_handler
coap_register_response_handler
coap_resize_binary
diff --git a/man/Makefile.am b/man/Makefile.am
index 7c7f024cc2..6025929680 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -196,6 +196,7 @@ install-man: install-man3 install-man5 install-man7
@echo ".so man3/coap_resource.3" > coap_resource_release_userdata_handler.3
@echo ".so man3/coap_resource.3" > coap_resource_get_uri_path.3
@echo ".so man3/coap_resource.3" > coap_get_resource_from_uri_path.3
+ @echo ".so man3/coap_resource.3" > coap_print_wellknown.3
@echo ".so man3/coap_session.3" > coap_session_get_addr_remote.3
@echo ".so man3/coap_session.3" > coap_session_get_context.3
@echo ".so man3/coap_session.3" > coap_session_get_ifindex.3
diff --git a/man/coap_handler.txt.in b/man/coap_handler.txt.in
index 59e95da016..0dd73b9e4d 100644
--- a/man/coap_handler.txt.in
+++ b/man/coap_handler.txt.in
@@ -16,7 +16,8 @@ coap_register_response_handler,
coap_register_nack_handler,
coap_register_ping_handler,
coap_register_pong_handler,
-coap_register_event_handler
+coap_register_event_handler,
+coap_register_print_wellknown_callback
- Work with CoAP handlers
SYNOPSIS
@@ -41,6 +42,9 @@ coap_pong_handler_t _handler_)*;
*void coap_register_event_handler(coap_context_t *_context_,
coap_event_handler_t _handler_)*;
+*void coap_register_print_wellknown_callback(coap_context_t *context,
+coap_print_wellknown_t callback);*
+
For specific (D)TLS library support, link with
*-lcoap-@LIBCOAP_API_VERSION@-notls*, *-lcoap-@LIBCOAP_API_VERSION@-gnutls*,
*-lcoap-@LIBCOAP_API_VERSION@-openssl*, *-lcoap-@LIBCOAP_API_VERSION@-mbedtls*,
@@ -388,6 +392,39 @@ typedef enum {
} coap_event_t;
----
+*Function: coap_register_print_wellknown_callback()*
+
+The *coap_register_print_wellknown_callback*() function registers a
+callback function that is called instead of the default *coap_print_wellknown*()
+function when the implicit .well-known/core resource is requested.
+
+The callback function prototype is defined as:
+[source, c]
+----
+/**
+ * @param context The context with the resource map.
+ * @param session The CoAP session.
+ * @param buf The buffer to write the result.
+ * @param buflen Must be initialized to the maximum length of buf and will be
+ * set to the length of the well-known response on return.
+ * @param offset The offset in bytes where the output shall start and is shifted
+ * accordingly with the characters that have been processed. This
+ * parameter is used to support the block option.
+ * @param query_filter A filter query according to Link Format
+ *
+ * @return COAP_PRINT_STATUS_ERROR on error. Otherwise, the lower 28 bits are
+ * set to the number of bytes that have actually been written to
+ * @p buf. COAP_PRINT_STATUS_TRUNC is set when the output has been
+ * truncated.
+ */
+typedef coap_print_status_t (*coap_print_wellknown_t)(coap_context_t *context,
+ coap_session_t *session,
+ unsigned char *buf,
+ size_t *buflen,
+ size_t offset,
+ const coap_string_t *query_filter);
+----
+
EXAMPLES
--------
*GET Resource Callback Handler*
diff --git a/man/coap_resource.txt.in b/man/coap_resource.txt.in
index cb881eb738..41adeba102 100644
--- a/man/coap_resource.txt.in
+++ b/man/coap_resource.txt.in
@@ -23,7 +23,8 @@ coap_resource_set_userdata,
coap_resource_get_userdata,
coap_resource_release_userdata_handler,
coap_resource_get_uri_path,
-coap_get_resource_from_uri_path
+coap_get_resource_from_uri_path,
+coap_print_wellknown
- Work with CoAP resources
SYNOPSIS
@@ -66,6 +67,10 @@ coap_resource_release_userdata_handler_t _callback_);*
*coap_resource_t *coap_get_resource_from_uri_path(coap_context_t *_context_,
coap_str_const_t *_uri_path_);*
+*coap_print_status_t coap_print_wellknown(coap_context_t *context,
+unsigned char *buf, size_t *buflen, size_t offset,
+const coap_string_t *query_filter);*
+
For specific (D)TLS library support, link with
*-lcoap-@LIBCOAP_API_VERSION@-notls*, *-lcoap-@LIBCOAP_API_VERSION@-gnutls*,
*-lcoap-@LIBCOAP_API_VERSION@-openssl*, *-lcoap-@LIBCOAP_API_VERSION@-mbedtls*,
@@ -292,6 +297,12 @@ the _resource_ definion.
The *coap_get_resource_from_uri_path*() function is used to return the resource
identified by the unique string _uri_path_ associated with _context_.
+*Function: coap_print_wellknown()*
+
+The *coap_print_wellknown*() function prints the names of all known resources
+of the given _context_ into _buf_ which has a maximum size of _buflen_. The
+first _offset_ bytes are skipped from the output to handle block transfers.
+The _query_filter_ is usually defined by the CoAP Uri-Query options as a query.
RETURN VALUES
-------------
@@ -312,6 +323,10 @@ there was a failure.
*coap_get_resource_from_uri_path*() returns the resource or NULL
if not found.
+*coap_print_wellknown*() returns COAP_PRINT_STATUS_ERROR on error. Otherwise,
+the lower 28 bits are set to the number of bytes that have actually been
+written. COAP_PRINT_STATUS_TRUNC is set when the output has been truncated.
+
EXAMPLES
--------
*Fixed Resources Set Up*
diff --git a/man/examples-code-check.c b/man/examples-code-check.c
index abf7dfb94b..ea5987dd6e 100644
--- a/man/examples-code-check.c
+++ b/man/examples-code-check.c
@@ -125,6 +125,7 @@ const char *number_list[] = {
"coap_pdu_type_t ",
"coap_mid_t ",
"coap_pdu_code_t ",
+ "coap_print_status_t ",
"coap_proto_t ",
"coap_session_state_t ",
"coap_session_type_t ",
diff --git a/src/coap_net.c b/src/coap_net.c
index 875274b278..7df2e21bee 100644
--- a/src/coap_net.c
+++ b/src/coap_net.c
@@ -2718,12 +2718,28 @@ coap_new_error_response(const coap_pdu_t *request, coap_pdu_code_t code,
* .well-known/core.
*/
COAP_STATIC_INLINE ssize_t
-get_wkc_len(coap_context_t *context, const coap_string_t *query_filter) {
+get_wkc_len(coap_context_t *context,
+ coap_session_t *session,
+ const coap_pdu_t *request,
+ const coap_string_t *query_filter) {
unsigned char buf[1];
size_t len = 0;
+ int result = 0;
- if (coap_print_wellknown(context, buf, &len, UINT_MAX, query_filter) &
- COAP_PRINT_STATUS_ERROR) {
+ if (context->print_wellknown_userdata) {
+ result = context->print_wellknown_userdata(context,
+ session,
+ request,
+ buf,
+ &len,
+ UINT_MAX,
+ query_filter);
+ } else {
+ coap_lock_lock(session->context, return COAP_PRINT_STATUS_ERROR);
+ result = coap_print_wellknown_lkd(context, buf, &len, UINT_MAX, query_filter);
+ coap_lock_unlock(session->context);
+ }
+ if (result & COAP_PRINT_STATUS_ERROR) {
coap_log_warn("cannot determine length of /.well-known/core\n");
return -1L;
}
@@ -2738,6 +2754,9 @@ free_wellknown_response(coap_session_t *session COAP_UNUSED, void *app_ptr) {
coap_delete_string(app_ptr);
}
+/*
+ * Caution - this handler is being treated as if in app space.
+ */
static void
hnd_get_wellknown(coap_resource_t *resource,
coap_session_t *session,
@@ -2747,7 +2766,7 @@ hnd_get_wellknown(coap_resource_t *resource,
size_t len = 0;
coap_string_t *data_string = NULL;
int result = 0;
- ssize_t wkc_len = get_wkc_len(session->context, query);
+ ssize_t wkc_len = get_wkc_len(session->context, session, request, query);
if (wkc_len) {
if (wkc_len < 0)
@@ -2757,8 +2776,19 @@ hnd_get_wellknown(coap_resource_t *resource,
goto error;
len = wkc_len;
- result = coap_print_wellknown(session->context, data_string->s, &len, 0,
- query);
+ if (session->context->print_wellknown_userdata) {
+ result = session->context->print_wellknown_userdata(session->context,
+ session,
+ request,
+ data_string->s,
+ &len,
+ 0,
+ query);
+ } else {
+ coap_lock_lock(session->context, goto error);
+ result = coap_print_wellknown_lkd(session->context, data_string->s, &len, 0, query);
+ coap_lock_unlock(session->context);
+ }
if ((result & COAP_PRINT_STATUS_ERROR) != 0) {
coap_log_debug("coap_print_wellknown failed\n");
goto error;
@@ -4701,6 +4731,12 @@ coap_mcast_per_resource(coap_context_t *context) {
context->mcast_per_resource = 1;
}
+void
+coap_register_print_wellknown_callback(coap_context_t *context,
+ coap_print_wellknown_t hnd) {
+ context->print_wellknown_userdata = hnd;
+}
+
#endif /* ! COAP_SERVER_SUPPORT */
#if COAP_CLIENT_SUPPORT
diff --git a/src/coap_resource.c b/src/coap_resource.c
index fe34acd183..8f48c83e34 100644
--- a/src/coap_resource.c
+++ b/src/coap_resource.c
@@ -102,12 +102,13 @@ match(const coap_str_const_t *text, const coap_str_const_t *pattern,
}
/**
- * Prints the names of all known resources to @p buf. This function
+ * Prints the names of all known resources for @p context to @p buf. This function
* sets @p buflen to the number of bytes actually written and returns
* @c 1 on succes. On error, the value in @p buflen is undefined and
* the return value will be @c 0.
*
* @param context The context with the resource map.
+ * @param session The CoAP session.
* @param buf The buffer to write the result.
* @param buflen Must be initialized to the maximum length of @p buf and will be
* set to the length of the well-known response on return.
@@ -122,16 +123,21 @@ match(const coap_str_const_t *text, const coap_str_const_t *pattern,
* @p buf. COAP_PRINT_STATUS_TRUNC is set when the output has been
* truncated.
*/
-#if defined(__GNUC__) && defined(WITHOUT_QUERY_FILTER)
coap_print_status_t
-coap_print_wellknown(coap_context_t *context, unsigned char *buf, size_t *buflen,
- size_t offset,
- const coap_string_t *query_filter COAP_UNUSED) {
-#else /* not a GCC */
+coap_print_wellknown(coap_context_t *context, unsigned char *buf,
+ size_t *buflen, size_t offset,
+ const coap_string_t *query_filter) {
+ coap_print_status_t result;
+ coap_lock_lock(context, return COAP_PRINT_STATUS_ERROR);
+ result = coap_print_wellknown_lkd(context, buf, buflen, offset, query_filter);
+ coap_lock_unlock(context);
+ return result;
+}
+
coap_print_status_t
-coap_print_wellknown(coap_context_t *context, unsigned char *buf, size_t *buflen,
- size_t offset, const coap_string_t *query_filter) {
-#endif /* GCC */
+coap_print_wellknown_lkd(coap_context_t *context, unsigned char *buf,
+ size_t *buflen, size_t offset,
+ const coap_string_t *query_filter) {
coap_print_status_t output_length = 0;
unsigned char *p = buf;
const uint8_t *bufend = buf + *buflen;
@@ -139,7 +145,9 @@ coap_print_wellknown(coap_context_t *context, unsigned char *buf, size_t *buflen
coap_print_status_t result;
const size_t old_offset = offset;
int subsequent_resource = 0;
-#ifndef WITHOUT_QUERY_FILTER
+#ifdef WITHOUT_QUERY_FILTER
+ (void)query_filter;
+#else
coap_str_const_t resource_param = { 0, NULL }, query_pattern = { 0, NULL };
int flags = 0; /* MATCH_SUBSTRING, MATCH_PREFIX, MATCH_URI */
#define MATCH_URI 0x01