diff --git a/include/coap3/coap_net_internal.h b/include/coap3/coap_net_internal.h index 6a2e8bff32..0db4e153e8 100644 --- a/include/coap3/coap_net_internal.h +++ b/include/coap3/coap_net_internal.h @@ -28,6 +28,24 @@ * @{ */ +/** + * Optional user callback to be used, when oscore_find_context can't find any context. + * Could be used to check external storage (e.g. FLASH). + * + * @param c_context The CoAP COntext to search. + * @param rcpkey_id The Recipient kid. + * @param ctxkey_id The ID Context to match (or NULL if no check). + * @param oscore_r2 Partial id_context to match against or NULL. + * @param recipient_ctx The recipient context to update. + * + * return The OSCORE context and @p recipient_ctx updated, or NULL is error. + */ +typedef oscore_ctx_t * (*external_oscore_find_context_handler_t)(const coap_context_t *c_context, + const coap_bin_const_t rcpkey_id, + const coap_bin_const_t *ctxkey_id, + uint8_t *oscore_r2, + oscore_recipient_ctx_t **recipient_ctx); + /** * Queue entry */ @@ -93,6 +111,8 @@ struct coap_context_t { #endif /* WITH_LWIP */ #if COAP_OSCORE_SUPPORT struct oscore_ctx_t *p_osc_ctx; /**< primary oscore context */ + external_oscore_find_context_handler_t external_oscore_find_context_handler; + /**< Called when oscore_find_context didn't find any context*/ #endif /* COAP_OSCORE_SUPPORT */ #if COAP_CLIENT_SUPPORT @@ -430,6 +450,17 @@ coap_mid_t coap_send_internal(coap_session_t *session, coap_pdu_t *pdu); */ int coap_client_delay_first(coap_session_t *session); +#if COAP_OSCORE_SUPPORT +/** + * Register optional user callback to be used, when oscore_find_context can't find any context. + * Callback could be used to check external storage (e.g. FLASH). + * + * @param ctx The current coap context to use. + * @param handler User callback. + */ +void coap_register_find_context_handler(coap_context_t *ctx, external_oscore_find_context_handler_t handler); +#endif + /** @} */ extern int coap_started; diff --git a/src/coap_net.c b/src/coap_net.c index 990c83ef1c..7e9619a756 100644 --- a/src/coap_net.c +++ b/src/coap_net.c @@ -576,6 +576,15 @@ coap_new_context(const coap_address_t *listen_addr) { #endif /* COAP_EPOLL_SUPPORT || COAP_SERVER_SUPPORT */ } +#if COAP_OSCORE_SUPPORT +void +coap_register_find_context_handler(coap_context_t *ctx, external_oscore_find_context_handler_t handler) +{ + assert(ctx); + ctx->external_oscore_find_context_handler = handler; +} +#endif + void coap_set_app_data(coap_context_t *ctx, void *app_data) { assert(ctx); diff --git a/src/oscore/oscore_context.c b/src/oscore/oscore_context.c index f9cd856235..14d58adf94 100644 --- a/src/oscore/oscore_context.c +++ b/src/oscore/oscore_context.c @@ -227,6 +227,13 @@ oscore_find_context(const coap_context_t *c_context, } /* while rpt */ pt = pt->next; } /* end while */ + + /* no context was found in libcoap RAM - call user function to also check external storage (e.g. FLASH) */ + if (c_context->external_oscore_find_context_handler) + { + return c_context->external_oscore_find_context_handler(c_context, rcpkey_id, ctxkey_id, oscore_r2, recipient_ctx); + } + return NULL; }