mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
nanocoap: add cache for response messages
This commit is contained in:
parent
59ec6f1ccd
commit
8750605d26
1
dist/tools/doccheck/exclude_patterns
vendored
1
dist/tools/doccheck/exclude_patterns
vendored
@ -14273,6 +14273,7 @@ sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_ACCEPT \(macro definiti
|
||||
sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_BLOCK1 \(macro definition\) of group net_coap is not documented\.
|
||||
sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_BLOCK2 \(macro definition\) of group net_coap is not documented\.
|
||||
sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_CONTENT_FORMAT \(macro definition\) of group net_coap is not documented\.
|
||||
sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_MAX_AGE \(macro definition\) of group net_coap is not documented\.
|
||||
sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_LOCATION_PATH \(macro definition\) of group net_coap is not documented\.
|
||||
sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_LOCATION_QUERY \(macro definition\) of group net_coap is not documented\.
|
||||
sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_OBSERVE \(macro definition\) of group net_coap is not documented\.
|
||||
|
@ -662,6 +662,11 @@ ifneq (,$(filter nanocoap_sock,$(USEMODULE)))
|
||||
USEMODULE += ztimer_msec
|
||||
endif
|
||||
|
||||
ifneq (,$(filter nanocoap_cache,$(USEMODULE)))
|
||||
USEMODULE += ztimer_sec
|
||||
USEMODULE += hashes
|
||||
endif
|
||||
|
||||
ifneq (,$(filter nanocoap_%,$(USEMODULE)))
|
||||
USEMODULE += nanocoap
|
||||
endif
|
||||
|
@ -40,6 +40,7 @@ extern "C" {
|
||||
#define COAP_OPT_LOCATION_PATH (8)
|
||||
#define COAP_OPT_URI_PATH (11)
|
||||
#define COAP_OPT_CONTENT_FORMAT (12)
|
||||
#define COAP_OPT_MAX_AGE (14)
|
||||
#define COAP_OPT_URI_QUERY (15)
|
||||
#define COAP_OPT_ACCEPT (17)
|
||||
#define COAP_OPT_LOCATION_QUERY (20)
|
||||
|
234
sys/include/net/nanocoap/cache.h
Normal file
234
sys/include/net/nanocoap/cache.h
Normal file
@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright (C) 2020 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup net_nanocoap_cache Nanocoap-Cache implementation
|
||||
* @ingroup net_nanocoap
|
||||
* @brief A cache implementation for nanocoap response messages
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief nanocoap-cache API
|
||||
*
|
||||
* @author Cenk Gündoğan <cenk.guendogan@haw-hamburg.de>
|
||||
*/
|
||||
|
||||
#ifndef NET_NANOCOAP_CACHE_H
|
||||
#define NET_NANOCOAP_CACHE_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include "clist.h"
|
||||
#include "net/nanocoap.h"
|
||||
#include "hashes/sha256.h"
|
||||
#include "ztimer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The number of maximum cache entries.
|
||||
*/
|
||||
#ifndef CONFIG_NANOCOAP_CACHE_ENTRIES
|
||||
#define CONFIG_NANOCOAP_CACHE_ENTRIES (8)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The length of the cache key in bytes.
|
||||
*/
|
||||
#ifndef CONFIG_NANOCOAP_CACHE_KEY_LENGTH
|
||||
#define CONFIG_NANOCOAP_CACHE_KEY_LENGTH (8)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Size of the buffer to store responses in the cache.
|
||||
*/
|
||||
#ifndef CONFIG_NANOCOAP_CACHE_RESPONSE_SIZE
|
||||
#define CONFIG_NANOCOAP_CACHE_RESPONSE_SIZE (128)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Cache container that holds a @p coap_pkt_t struct.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief needed for clist_t, must be the first struct member!
|
||||
*/
|
||||
clist_node_t node;
|
||||
|
||||
/**
|
||||
* @brief the calculated cache key, see nanocoap_cache_key_generate().
|
||||
*/
|
||||
uint8_t cache_key[CONFIG_NANOCOAP_CACHE_KEY_LENGTH];
|
||||
|
||||
/**
|
||||
* @brief packet representation of the response
|
||||
*/
|
||||
coap_pkt_t response_pkt;
|
||||
|
||||
/**
|
||||
* @brief buffer to hold the response message.
|
||||
*/
|
||||
uint8_t response_buf[CONFIG_NANOCOAP_CACHE_RESPONSE_SIZE];
|
||||
|
||||
size_t response_len; /**< length of the message in @p response */
|
||||
|
||||
unsigned request_method; /**< the method of the initial request */
|
||||
|
||||
/**
|
||||
* @brief absolute system time in seconds until which this cache entry
|
||||
* is considered valid.
|
||||
*/
|
||||
ztimer_now_t max_age;
|
||||
} nanocoap_cache_entry_t;
|
||||
|
||||
/**
|
||||
* @brief Typedef for the cache replacement strategy on full cache list.
|
||||
*
|
||||
* @return 0 on successfully replacing a cache element
|
||||
* @return -1 on error
|
||||
*/
|
||||
typedef int (*nanocoap_cache_replacement_strategy_t)(void);
|
||||
|
||||
/**
|
||||
* @brief Typedef for the cache update strategy on element access.
|
||||
*
|
||||
* @param[in] node The accessed node.
|
||||
*
|
||||
* @return 0 on successfully updating the element
|
||||
* @return -1 on error
|
||||
*/
|
||||
typedef int (*nanocoap_cache_update_strategy_t)(clist_node_t *node);
|
||||
|
||||
/**
|
||||
* @brief Initializes the internal state of the nanocoap cache.
|
||||
*/
|
||||
#if IS_USED(MODULE_NANOCOAP_CACHE)
|
||||
void nanocoap_cache_init(void);
|
||||
#else
|
||||
static inline void nanocoap_cache_init(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Returns the number of cached entries.
|
||||
*
|
||||
* @return Number of cached entries
|
||||
*/
|
||||
size_t nanocoap_cache_used_count(void);
|
||||
|
||||
/**
|
||||
* @brief Returns the number of unused cache entries.
|
||||
*
|
||||
* @return Number of unused cache entries
|
||||
*/
|
||||
size_t nanocoap_cache_free_count(void);
|
||||
|
||||
/**
|
||||
* @brief Determines if a response is cacheable and modifies the cache
|
||||
* as reflected in RFC7252, Section 5.9.
|
||||
|
||||
* @param[in] cache_key The cache key of the request
|
||||
* @param[in] request_method The method of the initial request
|
||||
* @param[in] resp The response to operate on
|
||||
* @param[in] resp_len The actual length of the response in @p resp
|
||||
*
|
||||
* @return 0 on successfully handling the response
|
||||
* @return -1 on error
|
||||
*/
|
||||
int nanocoap_cache_process(const uint8_t *cache_key, unsigned request_method,
|
||||
const coap_pkt_t *resp, size_t resp_len);
|
||||
/**
|
||||
* @brief Creates a new or gets an existing cache entry using the
|
||||
* request packet.
|
||||
*
|
||||
* @param[in] req The request to calculate the cache-key
|
||||
* @param[in] resp The response to add to the cache
|
||||
* @param[in] resp_len The actual length of the response message in @p resp
|
||||
*
|
||||
* @return The previously existing or newly added cache entry on success
|
||||
* @return NULL, if there is no space left
|
||||
*/
|
||||
nanocoap_cache_entry_t *nanocoap_cache_add_by_req(const coap_pkt_t *req,
|
||||
const coap_pkt_t *resp,
|
||||
size_t resp_len);
|
||||
|
||||
/**
|
||||
* @brief Creates a new or gets an existing cache entry using the cache key.
|
||||
*
|
||||
* @param[in] cache_key The cache key of the request
|
||||
* @param[in] request_method The method of the initial request
|
||||
* @param[in] resp The response to add to the cache
|
||||
* @param[in] resp_len The actual length of the response in @p resp
|
||||
*
|
||||
* @return The previously existing or newly added cache entry on success
|
||||
* @return NULL, if there is no space left
|
||||
*/
|
||||
nanocoap_cache_entry_t *nanocoap_cache_add_by_key(const uint8_t *cache_key,
|
||||
unsigned request_method,
|
||||
const coap_pkt_t *resp,
|
||||
size_t resp_len);
|
||||
|
||||
/**
|
||||
* @brief Performs a cache lookup based on the @p req.
|
||||
*
|
||||
* @param[in] req The request to calculate the cache-key
|
||||
*
|
||||
* @return An existing cache entry on cache hit
|
||||
* @return NULL on cache miss
|
||||
*/
|
||||
nanocoap_cache_entry_t *nanocoap_cache_request_lookup(const coap_pkt_t *req);
|
||||
|
||||
/**
|
||||
* @brief Performs a cache lookup based on the cache key of a request.
|
||||
*
|
||||
* @param[in] cache_key The cache key of a request
|
||||
*
|
||||
* @return An existing cache entry on cache hit
|
||||
* @return NULL on cache miss
|
||||
*/
|
||||
nanocoap_cache_entry_t *nanocoap_cache_key_lookup(const uint8_t *cache_key);
|
||||
|
||||
/**
|
||||
* @brief Deletes the provided cache entry @p ce.
|
||||
*
|
||||
* @param[in] ce The cache entry to delete
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 if entry is not available in the cache
|
||||
*/
|
||||
int nanocoap_cache_del(const nanocoap_cache_entry_t *ce);
|
||||
|
||||
/**
|
||||
* @brief Generates a cache key based on the request @p req.
|
||||
*
|
||||
* @param[in] req The request to generate the cache key from
|
||||
* @param[out] cache_key The generated cache key
|
||||
*/
|
||||
void nanocoap_cache_key_generate(const coap_pkt_t *req, uint8_t *cache_key);
|
||||
|
||||
/**
|
||||
* @brief Compares two cache keys.
|
||||
*
|
||||
* @param[in] cache_key1 The first cache key in the comparison
|
||||
* @param[in] cache_key2 The second cache key in the comparison
|
||||
*
|
||||
* @return 0 if cache keys are equal
|
||||
* @return <0 or 0> (see memcmp()) for unequal cache keys
|
||||
*/
|
||||
ssize_t nanocoap_cache_key_compare(uint8_t *cache_key1, uint8_t *cache_key2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* NET_NANOCOAP_CACHE_H */
|
||||
/** @} */
|
@ -35,4 +35,24 @@ config NANOCOAP_QS_MAX
|
||||
int "Maximum length of a query string written to a message"
|
||||
default 64
|
||||
|
||||
menuconfig KCONFIG_USEMODULE_NANOCOAP_CACHE
|
||||
bool "Configure Nanocoap Cache module"
|
||||
depends on USEMODULE_NANOCOAP_CACHE
|
||||
|
||||
if KCONFIG_USEMODULE_NANOCOAP_CACHE
|
||||
|
||||
config NANOCOAP_CACHE_ENTRIES
|
||||
int "Number of maximum cache entries"
|
||||
default 8
|
||||
|
||||
config NANOCOAP_CACHE_KEY_LENGTH
|
||||
int "The length of the cache key in bytes"
|
||||
default 8
|
||||
|
||||
config NANOCOAP_CACHE_RESPONSE_SIZE
|
||||
int "Size of the buffer to store responses in the cache"
|
||||
default 128
|
||||
|
||||
endif # KCONFIG_USEMODULE_NANOCOAP_CACHE
|
||||
|
||||
endif # KCONFIG_USEMODULE_NANOCOAP
|
||||
|
324
sys/net/application_layer/nanocoap/cache.c
Normal file
324
sys/net/application_layer/nanocoap/cache.c
Normal file
@ -0,0 +1,324 @@
|
||||
/*
|
||||
* Copyright (C) 2020 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup net_nanocoap_cache
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of common functions for the nanocoap-cache
|
||||
*
|
||||
* @author Cenk Gündoğan <cenk.guendogan@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "kernel_defines.h"
|
||||
#include "net/nanocoap/cache.h"
|
||||
#include "hashes/sha256.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
static clist_node_t _cache_list_head = { NULL };
|
||||
static clist_node_t _empty_list_head = { NULL };
|
||||
|
||||
static nanocoap_cache_entry_t _cache_entries[CONFIG_NANOCOAP_CACHE_ENTRIES];
|
||||
|
||||
static nanocoap_cache_replacement_strategy_t _replacement_strategy = NULL;
|
||||
|
||||
static int _cache_replacement_lru(void)
|
||||
{
|
||||
nanocoap_cache_entry_t *least = NULL;
|
||||
clist_node_t *it = _cache_list_head.next;
|
||||
|
||||
/* no element in the list */
|
||||
if (!it) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
least = container_of(it, nanocoap_cache_entry_t, node);
|
||||
|
||||
do {
|
||||
it = it->next;
|
||||
nanocoap_cache_entry_t *nit = container_of(it, nanocoap_cache_entry_t, node);
|
||||
if (least->access_time > nit->access_time) {
|
||||
least = nit;
|
||||
}
|
||||
} while (it != _cache_list_head.next);
|
||||
|
||||
return nanocoap_cache_del(least);
|
||||
}
|
||||
|
||||
void nanocoap_cache_init(void)
|
||||
{
|
||||
_cache_list_head.next = NULL;
|
||||
_empty_list_head.next = NULL;
|
||||
memset(_cache_entries, 0, sizeof(_cache_entries));
|
||||
/* construct list of empty entries */
|
||||
for (unsigned i = 0; i < CONFIG_NANOCOAP_CACHE_ENTRIES; i++) {
|
||||
clist_rpush(&_empty_list_head, &_cache_entries[i].node);
|
||||
}
|
||||
|
||||
/* hardcode cache replacement strategy for now */
|
||||
_replacement_strategy = _cache_replacement_lru;
|
||||
}
|
||||
|
||||
size_t nanocoap_cache_used_count(void)
|
||||
{
|
||||
return clist_count(&_cache_list_head);
|
||||
}
|
||||
|
||||
size_t nanocoap_cache_free_count(void)
|
||||
{
|
||||
return clist_count(&_empty_list_head);
|
||||
}
|
||||
|
||||
void nanocoap_cache_key_generate(const coap_pkt_t *req, uint8_t *cache_key)
|
||||
{
|
||||
sha256_context_t ctx;
|
||||
sha256_init(&ctx);
|
||||
|
||||
coap_optpos_t opt = {0, 0};
|
||||
uint8_t *value;
|
||||
|
||||
for (unsigned i = 0; i < req->options_len; i++) {
|
||||
ssize_t optlen = coap_opt_get_next(req, &opt, &value, !i);
|
||||
if (optlen >= 0) {
|
||||
/* skip NoCacheKey,
|
||||
see https://tools.ietf.org/html/rfc7252#section-5.4.6 */
|
||||
if ((opt.opt_num & 0x1E) == 0x1C) {
|
||||
continue;
|
||||
}
|
||||
sha256_update(&ctx, value, optlen);
|
||||
}
|
||||
}
|
||||
switch (req->hdr->code) {
|
||||
case COAP_METHOD_FETCH:
|
||||
sha256_update(&ctx, req->payload, req->payload_len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sha256_final(&ctx, cache_key);
|
||||
}
|
||||
|
||||
ssize_t nanocoap_cache_key_compare(uint8_t *cache_key1, uint8_t *cache_key2)
|
||||
{
|
||||
return memcmp(cache_key1, cache_key2, CONFIG_NANOCOAP_CACHE_KEY_LENGTH);
|
||||
}
|
||||
|
||||
static int _compare_cache_keys(clist_node_t *ce, void *arg)
|
||||
{
|
||||
nanocoap_cache_entry_t *iterator = container_of(ce, nanocoap_cache_entry_t, node);
|
||||
uint8_t *cache_key = (uint8_t *) arg;
|
||||
|
||||
if (!memcmp(iterator->cache_key, cache_key, CONFIG_NANOCOAP_CACHE_KEY_LENGTH)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static nanocoap_cache_entry_t *_nanocoap_cache_foreach(const uint8_t *key)
|
||||
{
|
||||
clist_node_t *node = clist_foreach(&_cache_list_head, _compare_cache_keys, (uint8_t *)key);
|
||||
|
||||
if (node != NULL) {
|
||||
return container_of(node, nanocoap_cache_entry_t, node);
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nanocoap_cache_entry_t *nanocoap_cache_key_lookup(const uint8_t *key)
|
||||
{
|
||||
nanocoap_cache_entry_t *ce = _nanocoap_cache_foreach(key);
|
||||
|
||||
if (ce) {
|
||||
ce->access_time = ztimer_now(ZTIMER_SEC);
|
||||
}
|
||||
|
||||
return ce;
|
||||
}
|
||||
|
||||
nanocoap_cache_entry_t *nanocoap_cache_request_lookup(const coap_pkt_t *req)
|
||||
{
|
||||
uint8_t cache_key[SHA256_DIGEST_LENGTH];
|
||||
nanocoap_cache_entry_t *ce;
|
||||
|
||||
/* generate cache key */
|
||||
nanocoap_cache_key_generate(req, cache_key);
|
||||
|
||||
/* check if cache key already exists */
|
||||
ce = nanocoap_cache_key_lookup(cache_key);
|
||||
|
||||
return ce;
|
||||
}
|
||||
|
||||
int nanocoap_cache_process(const uint8_t *cache_key, unsigned request_method,
|
||||
const coap_pkt_t *resp, size_t resp_len)
|
||||
{
|
||||
nanocoap_cache_entry_t *ce;
|
||||
ce = nanocoap_cache_key_lookup(cache_key);
|
||||
|
||||
/* This response is not cacheable. */
|
||||
if (resp->hdr->code == COAP_CODE_CREATED) {
|
||||
/* NO OP */
|
||||
}
|
||||
/* This response is not cacheable. However, a cache MUST mark any
|
||||
stored response for the deleted resource as not fresh.
|
||||
*/
|
||||
else if (resp->hdr->code == COAP_CODE_DELETED) {
|
||||
if (ce) {
|
||||
/* set max_age to now(), so that the cache is considered
|
||||
* stale immdiately */
|
||||
ce->max_age = ztimer_now(ZTIMER_SEC);
|
||||
}
|
||||
}
|
||||
/* When a cache that recognizes and processes the ETag response
|
||||
option receives a 2.03 (Valid) response, it MUST update the
|
||||
stored response with the value of the Max-Age Option included
|
||||
in the response (explicitly, or implicitly as a default value;
|
||||
see also Section 5.6.2). For each type of Safe-to-Forward
|
||||
option present in the response, the (possibly empty) set of
|
||||
options of this type that are present in the stored response
|
||||
MUST be replaced with the set of options of this type in the
|
||||
response received. (Unsafe options may trigger similar
|
||||
option-specific processing as defined by the option.)
|
||||
*/
|
||||
else if (resp->hdr->code == COAP_CODE_VALID) {
|
||||
if (ce) {
|
||||
/* refresh max_age() */
|
||||
uint32_t max_age = 60;
|
||||
coap_opt_get_uint((coap_pkt_t *)resp, COAP_OPT_MAX_AGE, &max_age);
|
||||
ce->max_age = ztimer_now(ZTIMER_SEC) + max_age;
|
||||
}
|
||||
/* TODO: handle the copying of the new options (if changed) */
|
||||
}
|
||||
/* This response is not cacheable. However, a cache MUST mark any
|
||||
stored response for the changed resource as not fresh.
|
||||
*/
|
||||
else if (resp->hdr->code == COAP_CODE_CHANGED) {
|
||||
if (ce) {
|
||||
/* set max_age to now(), so that the cache is considered
|
||||
* stale immdiately */
|
||||
ce->max_age = ztimer_now(ZTIMER_SEC);
|
||||
}
|
||||
}
|
||||
/* This response is cacheable: Caches can use the Max-Age Option
|
||||
to determine freshness and (if present) the
|
||||
ETag Option for validation.
|
||||
*/
|
||||
else if (resp->hdr->code == COAP_CODE_CONTENT) {
|
||||
uint32_t now = ztimer_now(ZTIMER_SEC);
|
||||
/* cache entry is stale */
|
||||
if (ce && (ce->max_age < now)) {
|
||||
nanocoap_cache_del(ce);
|
||||
}
|
||||
if (NULL == nanocoap_cache_add_by_key(cache_key, request_method,
|
||||
resp, resp_len)) {
|
||||
/* no space left in the cache? */
|
||||
return -1;
|
||||
}
|
||||
/* TODO: ETAG handling */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static nanocoap_cache_entry_t *_nanocoap_cache_pop(void)
|
||||
{
|
||||
clist_node_t *node;
|
||||
|
||||
node = clist_lpop(&_empty_list_head);
|
||||
if (node != NULL) {
|
||||
return container_of(node, nanocoap_cache_entry_t, node);
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nanocoap_cache_entry_t *nanocoap_cache_add_by_key(const uint8_t *cache_key,
|
||||
unsigned request_method,
|
||||
const coap_pkt_t *resp,
|
||||
size_t resp_len)
|
||||
{
|
||||
nanocoap_cache_entry_t *ce;
|
||||
ce = nanocoap_cache_key_lookup(cache_key);
|
||||
|
||||
/* found an already existing cache entry */
|
||||
if (ce) {
|
||||
return ce;
|
||||
}
|
||||
|
||||
/* did not find .. get an empty cache container */
|
||||
ce = _nanocoap_cache_pop();
|
||||
|
||||
/* no space left */
|
||||
if (!ce) {
|
||||
/* could not remove any entry */
|
||||
if (_replacement_strategy()) {
|
||||
return NULL;
|
||||
}
|
||||
/* could remove an entry */
|
||||
ce = _nanocoap_cache_pop();
|
||||
if (!ce) {
|
||||
/* still no free space ? stop trying now */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(ce->cache_key, cache_key, CONFIG_NANOCOAP_CACHE_KEY_LENGTH);
|
||||
memcpy(&ce->response_pkt, resp, sizeof(coap_pkt_t));
|
||||
memcpy(&ce->response_buf, resp->hdr, resp_len);
|
||||
ce->response_pkt.hdr = (coap_hdr_t *) ce->response_buf;
|
||||
ce->response_pkt.payload = ce->response_buf + (resp->payload - ((uint8_t *)resp->hdr));
|
||||
ce->response_len = resp_len;
|
||||
ce->access_time = ztimer_now(ZTIMER_SEC);
|
||||
ce->request_method = request_method;
|
||||
|
||||
/* default value is 60 seconds, if MAX_AGE not present */
|
||||
uint32_t max_age = 60;
|
||||
coap_opt_get_uint((coap_pkt_t *)resp, COAP_OPT_MAX_AGE, &max_age);
|
||||
ce->max_age = ztimer_now(ZTIMER_SEC) + max_age;
|
||||
|
||||
clist_rpush(&_cache_list_head, &ce->node);
|
||||
|
||||
return ce;
|
||||
}
|
||||
|
||||
nanocoap_cache_entry_t *nanocoap_cache_add_by_req(const coap_pkt_t *req,
|
||||
const coap_pkt_t *resp,
|
||||
size_t resp_len)
|
||||
{
|
||||
uint8_t cache_key[SHA256_DIGEST_LENGTH];
|
||||
|
||||
/* generate cache key */
|
||||
nanocoap_cache_key_generate(req, cache_key);
|
||||
|
||||
return nanocoap_cache_add_by_key(cache_key,
|
||||
coap_get_code((coap_pkt_t *)req),
|
||||
resp,
|
||||
resp_len);
|
||||
}
|
||||
|
||||
int nanocoap_cache_del(const nanocoap_cache_entry_t *ce)
|
||||
{
|
||||
clist_node_t *entry = clist_find(&_cache_list_head, &ce->node);
|
||||
|
||||
if (entry) {
|
||||
clist_remove(&_cache_list_head, entry);
|
||||
memset(entry, 0, sizeof(nanocoap_cache_entry_t));
|
||||
clist_rpush(&_empty_list_head, entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user