Skip to content

Commit 9ee47f2

Browse files
Julien Vermillardjhedberg
authored andcommitted
net: lwm2m: add cache filtering
Introduce `lwm2m_set_cache_filter()` so applications can drop cached samples before they reach the LwM2M SEND path. Fixes #91590 Signed-off-by: Julien Vermillard <[email protected]>
1 parent 70a1a49 commit 9ee47f2

File tree

5 files changed

+67
-3
lines changed

5 files changed

+67
-3
lines changed

doc/connectivity/networking/api/lwm2m.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -532,9 +532,9 @@ Read and Write operations
532532
Full content of data cache is written into a payload when any READ, SEND or NOTIFY operation
533533
internally reads the content of a given resource. This has a side effect that any read callbacks
534534
registered for a that resource are ignored when cache is enabled.
535-
Data is written into a cache when any of the ``lwm2m_set_*`` functions are called. To filter
536-
the data entering the cache, application may register a validation callback using
537-
:c:func:`lwm2m_register_validate_callback`.
535+
Data is written into a cache when any of the ``lwm2m_set_*`` functions are called. Applications can
536+
register a cache filter callback with :c:func:`lwm2m_set_cache_filter` to drop otherwise valid samples
537+
based on application-specific rules.
538538

539539
Limitations
540540
===========

include/zephyr/net/lwm2m.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,20 @@ struct lwm2m_time_series_elem {
348348
};
349349
};
350350

351+
/**
352+
* @typedef lwm2m_cache_filter_cb_t
353+
* @brief Callback type for filtering cached time series samples.
354+
*
355+
* Returning false skips storing the provided sample in the LwM2M cache.
356+
*
357+
* @param path Object path of the cached resource.
358+
* @param element Sample produced by the engine for the cache.
359+
*
360+
* @return true to keep the sample, false to discard it.
361+
*/
362+
typedef bool (*lwm2m_cache_filter_cb_t)(const struct lwm2m_obj_path *path,
363+
const struct lwm2m_time_series_elem *element);
364+
351365
/**
352366
* @brief Asynchronous callback to get a resource buffer and length.
353367
*
@@ -1590,6 +1604,21 @@ struct lwm2m_ctx *lwm2m_rd_client_ctx(void);
15901604
int lwm2m_enable_cache(const struct lwm2m_obj_path *path, struct lwm2m_time_series_elem *data_cache,
15911605
size_t cache_len);
15921606

1607+
/**
1608+
* @brief Register a filtering callback for cached resource samples.
1609+
*
1610+
* The callback is invoked whenever the LwM2M engine attempts to append a new
1611+
* sample to the resource cache. Returning false prevents the sample from being
1612+
* stored. Passing a NULL callback removes any previously registered filter.
1613+
*
1614+
* @param path LwM2M path to the cached resource.
1615+
* @param filter_cb Callback used to decide whether samples should be cached.
1616+
*
1617+
* @return 0 for success or a negative errno code in case of error.
1618+
*/
1619+
int lwm2m_set_cache_filter(const struct lwm2m_obj_path *path,
1620+
lwm2m_cache_filter_cb_t filter_cb);
1621+
15931622
/**
15941623
* @brief Security modes as defined in LwM2M Security object.
15951624
*/

subsys/net/lib/lwm2m/lwm2m_registry.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,7 @@ lwm2m_cache_entry_allocate(const struct lwm2m_obj_path *path)
14661466
for (i = 0; i < ARRAY_SIZE(lwm2m_cache_entries); i++) {
14671467
if (lwm2m_cache_entries[i].path.level == 0) {
14681468
lwm2m_cache_entries[i].path = *path;
1469+
lwm2m_cache_entries[i].filter_cb = NULL;
14691470
sys_slist_append(&lwm2m_timed_cache_list, &lwm2m_cache_entries[i].node);
14701471
return &lwm2m_cache_entries[i];
14711472
}
@@ -1542,6 +1543,14 @@ static void lwm2m_engine_cache_write(const struct lwm2m_engine_obj_field *obj_fi
15421543
break;
15431544
}
15441545

1546+
if (cache_entry->filter_cb &&
1547+
!cache_entry->filter_cb(&cache_entry->path, &elements)) {
1548+
LOG_DBG("Cache filter dropped sample for %u/%u/%u",
1549+
cache_entry->path.obj_id, cache_entry->path.obj_inst_id,
1550+
cache_entry->path.res_id);
1551+
return;
1552+
}
1553+
15451554
if (!lwm2m_cache_write(cache_entry, &elements)) {
15461555
LOG_WRN("Data cache full");
15471556
}
@@ -1628,6 +1637,29 @@ int lwm2m_enable_cache(const struct lwm2m_obj_path *path, struct lwm2m_time_seri
16281637
#endif /* CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT */
16291638
}
16301639

1640+
int lwm2m_set_cache_filter(const struct lwm2m_obj_path *path,
1641+
lwm2m_cache_filter_cb_t filter_cb)
1642+
{
1643+
#if defined(CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT)
1644+
struct lwm2m_time_series_resource *cache_entry;
1645+
1646+
if (path == NULL) {
1647+
return -EINVAL;
1648+
}
1649+
1650+
cache_entry = lwm2m_cache_entry_get_by_object(path);
1651+
if (cache_entry == NULL) {
1652+
return -ENOENT;
1653+
}
1654+
1655+
cache_entry->filter_cb = filter_cb;
1656+
1657+
return 0;
1658+
#else
1659+
return -ENOTSUP;
1660+
#endif /* CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT */
1661+
}
1662+
16311663
#if defined(CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT)
16321664
static int lwm2m_engine_data_cache_init(void)
16331665
{

subsys/net/lib/lwm2m/lwm2m_registry.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ struct lwm2m_time_series_resource {
209209
sys_snode_t node;
210210
/* Resource Path url */
211211
struct lwm2m_obj_path path;
212+
/* Optional filter for cached samples */
213+
lwm2m_cache_filter_cb_t filter_cb;
212214
/* Ring buffer */
213215
struct ring_buf rb;
214216
};

tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ ZTEST(lwm2m_registry, test_resource_cache)
628628
/* Resource cache is turned off */
629629
zassert_is_null(lwm2m_cache_entry_get_by_object(&path));
630630
zassert_equal(lwm2m_enable_cache(&path, &e, 1), -ENOTSUP);
631+
zassert_equal(lwm2m_set_cache_filter(&path, NULL), -ENOTSUP);
631632
zassert_false(lwm2m_cache_write(NULL, NULL));
632633
zassert_false(lwm2m_cache_read(NULL, NULL));
633634
zassert_equal(lwm2m_cache_size(NULL), 0);

0 commit comments

Comments
 (0)