Skip to content

Commit

Permalink
enable application control over .well-known/core responses
Browse files Browse the repository at this point in the history
  • Loading branch information
anyc authored and mrdeep1 committed May 31, 2024
1 parent 70469f2 commit 7c33808
Show file tree
Hide file tree
Showing 12 changed files with 198 additions and 22 deletions.
23 changes: 23 additions & 0 deletions include/coap3/coap_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "coap_pdu.h"
#include "coap_session.h"
#include "coap_debug.h"
#include "coap_resource.h"

/**
* @ingroup application_api
Expand Down Expand Up @@ -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);

/**@}*/

/**
Expand Down
2 changes: 2 additions & 0 deletions include/coap3/coap_net_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 27 additions & 0 deletions include/coap3/coap_resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <a href="http://tools.ietf.org/html/draft-ietf-core-link-format-11#section-4.1">Link Format</a>
*
* @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);

/** @} */

/**
Expand Down
30 changes: 26 additions & 4 deletions include/coap3/coap_resource_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <a href="http://tools.ietf.org/html/draft-ietf-core-link-format-11#section-4.1">Link Format</a>
*
* @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);

/** @} */

Expand Down
2 changes: 2 additions & 0 deletions libcoap-3.map
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions libcoap-3.sym
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions man/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 38 additions & 1 deletion man/coap_handler.txt.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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*,
Expand Down Expand Up @@ -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 <a href="http://tools.ietf.org/html/draft-ietf-core-link-format-11#section-4.1">Link Format</a>
*
* @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*
Expand Down
17 changes: 16 additions & 1 deletion man/coap_resource.txt.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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*,
Expand Down Expand Up @@ -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
-------------
Expand All @@ -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*
Expand Down
1 change: 1 addition & 0 deletions man/examples-code-check.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 ",
Expand Down
48 changes: 42 additions & 6 deletions src/coap_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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,
Expand All @@ -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)
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit 7c33808

Please sign in to comment.