tests: net: lwm2m: Add tests for lwm2m_engine.c

Add tests for lwm2m_engine.c using FFF framework.

Signed-off-by: Juha Ylinen <juha.ylinen@nordicsemi.no>
This commit is contained in:
Juha Ylinen 2023-02-22 10:05:22 +02:00 committed by Carles Cufí
commit 6b9d3c0a64
6 changed files with 611 additions and 0 deletions

View file

@ -0,0 +1,37 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(lwm2m_engine_test)
set(APP_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
# Add test sources
target_sources(app PRIVATE ${APP_SRC_DIR}/main.c)
target_sources(app PRIVATE ${APP_SRC_DIR}/stubs.c)
target_sources(app PRIVATE ${ZEPHYR_BASE}/subsys/net/lib/lwm2m/lwm2m_engine.c)
# Add includes directories
target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
target_include_directories(app PRIVATE ${ZEPHYR_BASE}/include/)
target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/net/lib/lwm2m/)
add_compile_definitions(CONFIG_LWM2M_ENGINE_MAX_PENDING=2)
add_compile_definitions(CONFIG_LWM2M_ENGINE_MAX_REPLIES=2)
add_compile_definitions(CONFIG_LWM2M_ENGINE_VALIDATION_BUFFER_SIZE=512)
add_compile_definitions(CONFIG_LWM2M_ENGINE_MESSAGE_HEADER_SIZE=512)
add_compile_definitions(CONFIG_LWM2M_ENGINE_MAX_OBSERVER=10)
add_compile_definitions(CONFIG_LWM2M_ENGINE_STACK_SIZE=2048)
add_compile_definitions(CONFIG_LWM2M_NUM_BLOCK1_CONTEXT=3)
add_compile_definitions(CONFIG_LWM2M_COAP_BLOCK_SIZE=256)
add_compile_definitions(CONFIG_LWM2M_COAP_MAX_MSG_SIZE=512)
add_compile_definitions(CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=60)
add_compile_definitions(CONFIG_LWM2M_SECURITY_INSTANCE_COUNT=1)
add_compile_definitions(CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY=30)
add_compile_definitions(CONFIG_LWM2M_QUEUE_MODE_UPTIME=30)
add_compile_definitions(CONFIG_LWM2M_LOG_LEVEL=4)
add_compile_definitions(CONFIG_NET_SOCKETS_POLL_MAX=3)
add_compile_definitions(CONFIG_LWM2M_DTLS_SUPPORT)
add_compile_definitions(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
add_compile_definitions(CONFIG_TLS_CREDENTIALS)
add_compile_definitions(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)

View file

@ -0,0 +1,3 @@
CONFIG_ZTEST=y
CONFIG_ZTEST_NEW_API=y
CONFIG_ZTEST_STACK_SIZE=4096

View file

@ -0,0 +1,362 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/fff.h>
#include <zephyr/logging/log.h>
#include <zephyr/ztest.h>
#include "lwm2m_engine.h"
#include "lwm2m_rd_client.h"
#include "stubs.h"
LOG_MODULE_REGISTER(lwm2m_engine_test);
DEFINE_FFF_GLOBALS;
#define FFF_FAKES_LIST(FAKE)
static uint8_t my_buf[256];
static struct lwm2m_message my_msg;
static struct lwm2m_engine_obj_field my_obj_field;
static int lwm2m_get_res_buf_custom_fake(const struct lwm2m_obj_path *path, void **buffer_ptr,
uint16_t *buffer_len, uint16_t *data_len,
uint8_t *data_flags)
{
if (buffer_ptr)
*buffer_ptr = my_buf;
if (buffer_len)
*buffer_len = sizeof(my_buf);
if (data_len)
*data_len = 1;
return 0;
}
static struct lwm2m_message *find_msg_custom_fake(struct coap_pending *pending,
struct coap_reply *reply)
{
return &my_msg;
}
static struct lwm2m_engine_obj_field *
lwm2m_get_engine_obj_field_custom_fake(struct lwm2m_engine_obj *obj, int res_id)
{
return &my_obj_field;
}
static int lwm2m_get_bool_custom_fake(const struct lwm2m_obj_path *path, bool *value)
{
*value = false;
return 0;
}
static void test_service(struct k_work *work)
{
LOG_INF("Test service");
k_sleep(K_MSEC(10));
}
static void setup(void *data)
{
/* Register resets */
DO_FOREACH_FAKE(RESET_FAKE);
/* reset common FFF internal structures */
FFF_RESET_HISTORY();
clear_socket_events();
lwm2m_get_res_buf_fake.custom_fake = lwm2m_get_res_buf_custom_fake;
find_msg_fake.custom_fake = find_msg_custom_fake;
lwm2m_get_engine_obj_field_fake.custom_fake = lwm2m_get_engine_obj_field_custom_fake;
lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_custom_fake;
}
ZTEST_SUITE(lwm2m_engine, NULL, NULL, setup, NULL, NULL);
ZTEST(lwm2m_engine, test_start_stop)
{
int ret;
struct lwm2m_ctx ctx;
char host_name[10] = "my_host";
(void)memset(&ctx, 0x0, sizeof(ctx));
ctx.remote_addr.sa_family = AF_INET;
ctx.sock_fd = -1;
ctx.load_credentials = NULL;
ctx.desthostname = host_name;
ctx.desthostnamelen = strlen(host_name);
ctx.hostname_verify = true;
ctx.use_dtls = true;
ret = lwm2m_engine_start(&ctx);
zassert_equal(ret, 0);
/* wait for socket receive thread */
k_sleep(K_MSEC(1000));
ret = lwm2m_engine_stop(&ctx);
zassert_equal(ret, 0);
}
ZTEST(lwm2m_engine, test_pause_resume)
{
int ret;
struct lwm2m_ctx ctx;
(void)memset(&ctx, 0x0, sizeof(ctx));
ctx.remote_addr.sa_family = AF_INET;
ctx.sock_fd = -1;
ctx.load_credentials = NULL;
ret = lwm2m_engine_start(&ctx);
zassert_equal(ret, 0);
ret = lwm2m_engine_resume();
zassert_equal(ret, -EPERM);
ret = lwm2m_engine_pause();
zassert_equal(ret, 0);
ret = lwm2m_engine_pause();
zassert_equal(ret, 0);
ret = lwm2m_engine_resume();
zassert_equal(ret, 0);
ret = lwm2m_engine_stop(&ctx);
zassert_equal(ret, 0);
}
ZTEST(lwm2m_engine, test_engine_add_service)
{
int ret;
struct lwm2m_ctx ctx;
(void)memset(&ctx, 0x0, sizeof(ctx));
ctx.remote_addr.sa_family = AF_INET;
ctx.load_credentials = NULL;
ret = lwm2m_engine_start(&ctx);
zassert_equal(ret, 0);
ret = lwm2m_engine_add_service(test_service, 1000);
zassert_equal(ret, 0);
/* wait for socket receive thread */
k_sleep(K_MSEC(1500));
ret = lwm2m_engine_update_service_period(test_service, 500);
zassert_equal(ret, 0);
ret = lwm2m_engine_stop(&ctx);
zassert_equal(ret, 0);
}
ZTEST(lwm2m_engine, test_no_sa_family)
{
int ret;
struct lwm2m_ctx ctx;
(void)memset(&ctx, 0x0, sizeof(ctx));
ctx.sock_fd = -1;
ctx.load_credentials = NULL;
ret = lwm2m_engine_start(&ctx);
zassert_equal(ret, -EPROTONOSUPPORT);
}
ZTEST(lwm2m_engine, test_socket_suspend_resume_connection)
{
int ret;
struct lwm2m_ctx ctx;
(void)memset(&ctx, 0x0, sizeof(ctx));
ctx.sock_fd = -1;
ctx.load_credentials = NULL;
ctx.remote_addr.sa_family = AF_INET;
ret = lwm2m_engine_start(&ctx);
zassert_equal(ret, 0);
ret = lwm2m_socket_suspend(&ctx);
zassert_equal(ret, 0);
zassert_equal(ctx.connection_suspended, true);
ret = lwm2m_engine_connection_resume(&ctx);
zassert_equal(ret, 0);
zassert_equal(ctx.connection_suspended, false);
}
ZTEST(lwm2m_engine, test_check_notifications)
{
int ret;
struct lwm2m_ctx ctx;
struct observe_node obs;
(void)memset(&ctx, 0x0, sizeof(ctx));
ctx.sock_fd = -1;
ctx.load_credentials = NULL;
ctx.remote_addr.sa_family = AF_INET;
sys_slist_init(&ctx.observer);
obs.last_timestamp = k_uptime_get();
obs.event_timestamp = k_uptime_get() + 1000U;
obs.resource_update = false;
obs.active_tx_operation = false;
sys_slist_append(&ctx.observer, &obs.node);
lwm2m_rd_client_is_registred_fake.return_val = true;
ret = lwm2m_engine_start(&ctx);
zassert_equal(ret, 0);
/* wait for socket receive thread */
k_sleep(K_MSEC(2000));
ret = lwm2m_engine_stop(&ctx);
zassert_equal(ret, 0);
zassert_equal(generate_notify_message_fake.call_count, 1, "Notify message not generated");
zassert_equal(engine_observe_shedule_next_event_fake.call_count, 1,
"Next observe event not scheduled");
}
ZTEST(lwm2m_engine, test_push_queued_buffers)
{
int ret;
struct lwm2m_ctx ctx;
struct lwm2m_message msg;
(void)memset(&ctx, 0x0, sizeof(ctx));
sys_slist_init(&ctx.queued_messages);
msg.ctx = &ctx;
sys_slist_append(&ctx.queued_messages, &msg.node);
ret = lwm2m_push_queued_buffers(&ctx);
zassert_equal(ret, 0);
}
ZTEST(lwm2m_engine, test_validate_write_access)
{
int ret;
struct lwm2m_ctx ctx;
struct lwm2m_message msg;
struct lwm2m_engine_res resources;
struct lwm2m_engine_obj_inst obj_inst;
struct lwm2m_engine_obj_field *obj_field = NULL;
(void)memset(&ctx, 0x0, sizeof(ctx));
ctx.bootstrap_mode = true;
msg.ctx = &ctx;
msg.path = LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0);
obj_inst.resources = &resources;
obj_inst.resource_count = 1U;
ret = lwm2m_engine_validate_write_access(&msg, &obj_inst, &obj_field);
zassert_equal(ret, 0);
obj_inst.resource_count = 0U;
ret = lwm2m_engine_validate_write_access(&msg, &obj_inst, &obj_field);
zassert_equal(ret, -EINVAL);
msg.path = LWM2M_OBJ(LWM2M_OBJECT_DEVICE_ID, 0);
ret = lwm2m_engine_validate_write_access(&msg, &obj_inst, &obj_field);
zassert_equal(ret, -EPERM);
}
ZTEST(lwm2m_engine, test_bootstrap_delete)
{
int ret;
struct lwm2m_message msg;
msg.path = LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 0);
ret = bootstrap_delete(&msg);
zassert_equal(ret, -EPERM);
msg.path = LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0);
ret = bootstrap_delete(&msg);
zassert_equal(ret, 0);
msg.path = LWM2M_OBJ(LWM2M_OBJECT_DEVICE_ID, 0);
ret = bootstrap_delete(&msg);
zassert_equal(ret, -EPERM);
}
ZTEST(lwm2m_engine, test_retransmit_request)
{
int ret;
struct lwm2m_ctx ctx;
struct coap_pending pending_1;
struct coap_pending pending_2;
(void)memset(&ctx, 0x0, sizeof(ctx));
ctx.sock_fd = -1;
ctx.load_credentials = NULL;
ctx.remote_addr.sa_family = AF_INET;
pending_1.t0 = k_uptime_get();
pending_1.timeout = 200U;
pending_1.retries = 0;
ctx.pendings[0] = pending_1;
pending_2.t0 = k_uptime_get();
pending_2.timeout = 200U;
pending_2.retries = 1;
ctx.pendings[1] = pending_2;
ret = lwm2m_engine_start(&ctx);
zassert_equal(ret, 0);
/* wait for socket receive thread */
k_sleep(K_MSEC(500));
ret = lwm2m_engine_stop(&ctx);
zassert_equal(ret, 0);
zassert_equal(lwm2m_reset_message_fake.call_count, 1, "Message was not reseted");
zassert_equal(lwm2m_send_message_async_fake.call_count, 1, "Message was not sent");
}
ZTEST(lwm2m_engine, test_socket_recv)
{
int ret;
struct lwm2m_ctx ctx;
(void)memset(&ctx, 0x0, sizeof(ctx));
ctx.remote_addr.sa_family = AF_INET;
ctx.sock_fd = -1;
set_socket_events(ZSOCK_POLLIN);
ret = lwm2m_engine_start(&ctx);
zassert_equal(ret, 0);
/* wait for socket receive thread */
k_sleep(K_MSEC(1000));
ret = lwm2m_engine_stop(&ctx);
zassert_equal(ret, 0);
zassert_equal(lwm2m_udp_receive_fake.call_count, 1, "udp receive was not called");
}
ZTEST(lwm2m_engine, test_socket_send)
{
int ret;
struct lwm2m_ctx ctx;
struct lwm2m_message msg;
(void)memset(&ctx, 0x0, sizeof(ctx));
ctx.remote_addr.sa_family = AF_INET;
ctx.sock_fd = -1;
sys_slist_init(&ctx.queued_messages);
msg.ctx = &ctx;
msg.type = COAP_TYPE_CON;
sys_slist_append(&ctx.queued_messages, &msg.node);
ret = lwm2m_push_queued_buffers(&ctx);
zassert_equal(ret, 0);
set_socket_events(ZSOCK_POLLOUT);
ret = lwm2m_engine_start(&ctx);
zassert_equal(ret, 0);
/* wait for socket receive thread */
k_sleep(K_MSEC(2000));
ret = lwm2m_engine_stop(&ctx);
zassert_equal(ret, 0);
LOG_INF("Count %d", coap_pending_cycle_fake.call_count);
zassert_equal(coap_pending_cycle_fake.call_count, 1, "coap_pending_cycle not called");
}

View file

@ -0,0 +1,119 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/logging/log.h>
#include <stubs.h>
LOG_MODULE_DECLARE(lwm2m_engine_test);
DEFINE_FAKE_VALUE_FUNC(int, lwm2m_rd_client_pause);
DEFINE_FAKE_VALUE_FUNC(int, lwm2m_rd_client_resume);
DEFINE_FAKE_VALUE_FUNC(struct lwm2m_message *, find_msg, struct coap_pending *,
struct coap_reply *);
DEFINE_FAKE_VOID_FUNC(coap_pending_clear, struct coap_pending *);
DEFINE_FAKE_VOID_FUNC(lwm2m_reset_message, struct lwm2m_message *, bool);
DEFINE_FAKE_VALUE_FUNC(int, lwm2m_send_message_async, struct lwm2m_message *);
DEFINE_FAKE_VOID_FUNC(lwm2m_registry_lock);
DEFINE_FAKE_VOID_FUNC(lwm2m_registry_unlock);
DEFINE_FAKE_VALUE_FUNC(bool, coap_pending_cycle, struct coap_pending *);
DEFINE_FAKE_VALUE_FUNC(int, generate_notify_message, struct lwm2m_ctx *, struct observe_node *,
void *);
DEFINE_FAKE_VALUE_FUNC(int64_t, engine_observe_shedule_next_event, struct observe_node *, uint16_t,
const int64_t);
DEFINE_FAKE_VALUE_FUNC(int, handle_request, struct coap_packet *, struct lwm2m_message *);
DEFINE_FAKE_VOID_FUNC(lwm2m_udp_receive, struct lwm2m_ctx *, uint8_t *, uint16_t, struct sockaddr *,
udp_request_handler_cb_t);
DEFINE_FAKE_VALUE_FUNC(bool, lwm2m_rd_client_is_registred, struct lwm2m_ctx *);
DEFINE_FAKE_VOID_FUNC(lwm2m_engine_context_close, struct lwm2m_ctx *);
DEFINE_FAKE_VALUE_FUNC(int, lwm2m_get_res_buf, const struct lwm2m_obj_path *, void **, uint16_t *,
uint16_t *, uint8_t *);
DEFINE_FAKE_VALUE_FUNC(int, lwm2m_parse_peerinfo, char *, struct lwm2m_ctx *, bool);
DEFINE_FAKE_VALUE_FUNC(int, tls_credential_add, sec_tag_t, enum tls_credential_type, const void *,
size_t);
DEFINE_FAKE_VALUE_FUNC(int, tls_credential_delete, sec_tag_t, enum tls_credential_type);
DEFINE_FAKE_VALUE_FUNC(struct lwm2m_engine_obj_field *, lwm2m_get_engine_obj_field,
struct lwm2m_engine_obj *, int);
DEFINE_FAKE_VALUE_FUNC(int, lwm2m_get_bool, const struct lwm2m_obj_path *, bool *);
DEFINE_FAKE_VALUE_FUNC(sys_slist_t *, lwm2m_engine_obj_inst_list);
DEFINE_FAKE_VALUE_FUNC(int, lwm2m_delete_obj_inst, uint16_t, uint16_t);
static sys_slist_t obs_obj_path_list;
sys_slist_t *lwm2m_obs_obj_path_list(void)
{
return &obs_obj_path_list;
}
struct zsock_pollfd {
int fd;
short events;
short revents;
};
static short my_events;
void set_socket_events(short events)
{
my_events |= events;
}
void clear_socket_events(void)
{
my_events = 0;
}
int z_impl_zsock_socket(int family, int type, int proto)
{
return 0;
}
int z_impl_zsock_close(int sock)
{
return 0;
}
int z_impl_zsock_connect(int sock, const struct sockaddr *addr, socklen_t addrlen)
{
return 0;
}
ssize_t z_impl_zsock_sendto(int sock, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen)
{
k_sleep(K_MSEC(1));
if (my_events & ZSOCK_POLLOUT) {
my_events = 0;
}
return 1;
}
ssize_t z_impl_zsock_recvfrom(int sock, void *buf, size_t max_len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen)
{
k_sleep(K_MSEC(1));
if (my_events & ZSOCK_POLLIN) {
my_events = 0;
return 1;
}
errno = EWOULDBLOCK;
return -1;
}
int z_impl_zsock_poll(struct zsock_pollfd *fds, int nfds, int poll_timeout)
{
k_sleep(K_MSEC(poll_timeout));
fds->revents = my_events;
return 0;
}
int z_impl_zsock_setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen)
{
return 0;
}
int z_impl_zsock_fcntl(int sock, int cmd, int flags)
{
return 0;
}

View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef STUBS_H
#define STUBS_H
#include <stdbool.h>
#include <stdint.h>
#include <zephyr/fff.h>
#include <zephyr/net/lwm2m.h>
#include <zephyr/ztest.h>
#include <zephyr/net/tls_credentials.h>
#include "lwm2m_message_handling.h"
#define ZSOCK_POLLIN 1
#define ZSOCK_POLLOUT 4
void set_socket_events(short events);
void clear_socket_events(void);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_rd_client_pause);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_rd_client_resume);
DECLARE_FAKE_VALUE_FUNC(struct lwm2m_message *, find_msg, struct coap_pending *,
struct coap_reply *);
DECLARE_FAKE_VOID_FUNC(coap_pending_clear, struct coap_pending *);
DECLARE_FAKE_VOID_FUNC(lwm2m_reset_message, struct lwm2m_message *, bool);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_send_message_async, struct lwm2m_message *);
DECLARE_FAKE_VOID_FUNC(lwm2m_registry_lock);
DECLARE_FAKE_VOID_FUNC(lwm2m_registry_unlock);
DECLARE_FAKE_VALUE_FUNC(bool, coap_pending_cycle, struct coap_pending *);
DECLARE_FAKE_VALUE_FUNC(int, generate_notify_message, struct lwm2m_ctx *, struct observe_node *,
void *);
DECLARE_FAKE_VALUE_FUNC(int64_t, engine_observe_shedule_next_event, struct observe_node *, uint16_t,
const int64_t);
DECLARE_FAKE_VALUE_FUNC(int, handle_request, struct coap_packet *, struct lwm2m_message *);
DECLARE_FAKE_VOID_FUNC(lwm2m_udp_receive, struct lwm2m_ctx *, uint8_t *, uint16_t,
struct sockaddr *, udp_request_handler_cb_t);
DECLARE_FAKE_VALUE_FUNC(bool, lwm2m_rd_client_is_registred, struct lwm2m_ctx *);
DECLARE_FAKE_VOID_FUNC(lwm2m_engine_context_close, struct lwm2m_ctx *);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_get_res_buf, const struct lwm2m_obj_path *, void **, uint16_t *,
uint16_t *, uint8_t *);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_parse_peerinfo, char *, struct lwm2m_ctx *, bool);
DECLARE_FAKE_VALUE_FUNC(int, tls_credential_add, sec_tag_t, enum tls_credential_type, const void *,
size_t);
DECLARE_FAKE_VALUE_FUNC(int, tls_credential_delete, sec_tag_t, enum tls_credential_type);
DECLARE_FAKE_VALUE_FUNC(struct lwm2m_engine_obj_field *, lwm2m_get_engine_obj_field,
struct lwm2m_engine_obj *, int);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_get_bool, const struct lwm2m_obj_path *, bool *);
DECLARE_FAKE_VALUE_FUNC(sys_slist_t *, lwm2m_engine_obj_inst_list);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_delete_obj_inst, uint16_t, uint16_t);
#define DO_FOREACH_FAKE(FUNC) \
do { \
FUNC(lwm2m_rd_client_pause) \
FUNC(lwm2m_rd_client_resume) \
FUNC(find_msg) \
FUNC(coap_pending_clear) \
FUNC(lwm2m_reset_message) \
FUNC(lwm2m_send_message_async) \
FUNC(lwm2m_registry_lock) \
FUNC(lwm2m_registry_unlock) \
FUNC(coap_pending_cycle) \
FUNC(generate_notify_message) \
FUNC(engine_observe_shedule_next_event) \
FUNC(handle_request) \
FUNC(lwm2m_udp_receive) \
FUNC(lwm2m_rd_client_is_registred) \
FUNC(lwm2m_engine_context_close) \
FUNC(lwm2m_get_res_buf) \
FUNC(lwm2m_parse_peerinfo) \
FUNC(tls_credential_add) \
FUNC(tls_credential_delete) \
FUNC(lwm2m_get_engine_obj_field) \
FUNC(lwm2m_get_bool) \
FUNC(lwm2m_engine_obj_inst_list) \
FUNC(lwm2m_delete_obj_inst) \
} while (0)
#endif /* STUBS_H */

View file

@ -0,0 +1,6 @@
common:
depends_on: netif
tests:
subsys.net.lib.lwm2m.lwm2m_engine:
platform_allow: native_posix
tags: lwm2m net