net: lwm2m: Transmission state indications

Allow engine to give hints about ongoing CoAP transmissions.
This information can be used to control various power saving
modes for network interfaces. For example cellular networks might
support release assist indicator.

Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
This commit is contained in:
Seppo Takalo 2023-11-09 11:59:09 +02:00 committed by Fabio Baltieri
commit 6161fbdf21
7 changed files with 155 additions and 4 deletions

View file

@ -13,10 +13,11 @@
#include "lwm2m_rd_client.h"
#include "stubs.h"
#if defined(CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME)
#if defined(CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME)
#include "timer_model.h"
#endif
#define LOG_LEVEL LOG_LEVEL_DBG
LOG_MODULE_REGISTER(lwm2m_engine_test);
DEFINE_FFF_GLOBALS;
@ -67,7 +68,7 @@ static void test_service(struct k_work *work)
static void setup(void *data)
{
#if defined(CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME)
#if defined(CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME)
/* It is enough that some slow-down is happening on sleeps, it does not have to be
* real time
*/
@ -467,3 +468,70 @@ ZTEST(lwm2m_engine, test_security)
zassert_equal(tls_credential_add_fake.arg1_history[2], TLS_CREDENTIAL_CA_CERTIFICATE);
zassert_equal(lwm2m_engine_stop(&ctx), 0);
}
static enum lwm2m_socket_states last_state;
static void socket_state(int fd, enum lwm2m_socket_states state)
{
(void) fd;
last_state = state;
}
ZTEST(lwm2m_engine, test_socket_state)
{
int ret;
struct lwm2m_ctx ctx = {
.remote_addr.sa_family = AF_INET,
.sock_fd = -1,
.set_socket_state = socket_state,
};
struct lwm2m_message msg1 = {
.ctx = &ctx,
.type = COAP_TYPE_CON,
};
struct lwm2m_message msg2 = msg1;
struct lwm2m_message ack = {
.ctx = &ctx,
.type = COAP_TYPE_ACK,
};
sys_slist_init(&ctx.pending_sends);
ret = lwm2m_engine_start(&ctx);
zassert_equal(ret, 0);
/* One confimable in queue, should cause ONE_RESPONSE status */
coap_pendings_count_fake.return_val = 1;
sys_slist_append(&ctx.pending_sends, &msg1.node);
set_socket_events(ZSOCK_POLLOUT);
k_sleep(K_MSEC(100));
zassert_equal(last_state, LWM2M_SOCKET_STATE_ONE_RESPONSE);
/* More than one messages in queue, not empty, should cause ONGOING */
coap_pendings_count_fake.return_val = 2;
sys_slist_append(&ctx.pending_sends, &msg1.node);
sys_slist_append(&ctx.pending_sends, &msg2.node);
set_socket_events(ZSOCK_POLLOUT);
k_sleep(K_MSEC(100));
zassert_equal(last_state, LWM2M_SOCKET_STATE_ONGOING);
/* Last out, while waiting for ACK to both, should still cause ONGOING */
coap_pendings_count_fake.return_val = 2;
set_socket_events(ZSOCK_POLLOUT);
k_sleep(K_MSEC(100));
zassert_equal(last_state, LWM2M_SOCKET_STATE_ONGOING);
/* Only one Ack transmiting, nothing expected back -> LAST */
coap_pendings_count_fake.return_val = 0;
sys_slist_append(&ctx.pending_sends, &ack.node);
set_socket_events(ZSOCK_POLLOUT);
k_sleep(K_MSEC(100));
zassert_equal(last_state, LWM2M_SOCKET_STATE_LAST);
/* Socket suspended (as in QUEUE_RX_OFF), should cause NO_DATA */
ret = lwm2m_socket_suspend(&ctx);
zassert_equal(ret, 0);
zassert_equal(last_state, LWM2M_SOCKET_STATE_NO_DATA);
ret = lwm2m_engine_stop(&ctx);
zassert_equal(ret, 0);
}

View file

@ -19,6 +19,7 @@ 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(size_t, coap_pendings_count, struct coap_pending *, size_t);
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,
@ -41,6 +42,7 @@ DEFINE_FAKE_VALUE_FUNC(int, lwm2m_delete_obj_inst, uint16_t, uint16_t);
DEFINE_FAKE_VOID_FUNC(lwm2m_clear_block_contexts);
DEFINE_FAKE_VALUE_FUNC(int, lwm2m_security_mode, struct lwm2m_ctx *);
DEFINE_FAKE_VALUE_FUNC(int, z_impl_zsock_setsockopt, int, int, int, const void *, socklen_t);
DEFINE_FAKE_VOID_FUNC(engine_update_tx_time);
static sys_slist_t obs_obj_path_list = SYS_SLIST_STATIC_INIT(&obs_obj_path_list);
sys_slist_t *lwm2m_obs_obj_path_list(void)

View file

@ -28,6 +28,7 @@ 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_VALUE_FUNC(size_t, coap_pendings_count, struct coap_pending *, size_t);
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);
@ -56,6 +57,7 @@ DECLARE_FAKE_VOID_FUNC(lwm2m_clear_block_contexts);
DECLARE_FAKE_VALUE_FUNC(int, z_impl_zsock_connect, int, const struct sockaddr *, socklen_t);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_mode, struct lwm2m_ctx *);
DECLARE_FAKE_VALUE_FUNC(int, z_impl_zsock_setsockopt, int, int, int, const void *, socklen_t);
DECLARE_FAKE_VOID_FUNC(engine_update_tx_time);
#define DO_FOREACH_FAKE(FUNC) \
do { \
@ -63,6 +65,7 @@ DECLARE_FAKE_VALUE_FUNC(int, z_impl_zsock_setsockopt, int, int, int, const void
FUNC(lwm2m_rd_client_resume) \
FUNC(find_msg) \
FUNC(coap_pending_clear) \
FUNC(coap_pendings_count) \
FUNC(lwm2m_reset_message) \
FUNC(lwm2m_send_message_async) \
FUNC(lwm2m_registry_lock) \
@ -85,6 +88,7 @@ DECLARE_FAKE_VALUE_FUNC(int, z_impl_zsock_setsockopt, int, int, int, const void
FUNC(z_impl_zsock_connect) \
FUNC(lwm2m_security_mode) \
FUNC(z_impl_zsock_setsockopt) \
FUNC(engine_update_tx_time) \
} while (0)
#endif /* STUBS_H */