net: lwm2m: Implement fallback mechanism and support for diable

If server registration fails, allow fallback to secondary server,
or fallback to bootstrap.
Also allow fallback to different bootstrap server.

Add API to tell RD client when server have been disabled by
executable command.

Changes to RD state machine:
* All retry logic should be handled in NETWORK_ERROR state.
* New state SERVER_DISABLED.
* Internally disable servers that reject registration
* Temporary disable server on network error.
* Clean up all "disable timers" on start.
* Select server first, then find security object for it.
* State functions return void, error handling is done using states.
* DISCONNECT event will only come when client is requested to stop.
* NETWORK_ERROR will stop engine. This is generic error for all kinds
  of registration or network failures.
* BOOTSTRAP_REG_FAILURE also stops engine. This is fatal, and we cannot
  recover.

Refactoring:
* Server selection logic is inside server object.
* sm_handle_timeout_state() does not require msg parameter. Unused.
* When bootstrap fail, we should NOT back off to registration.
  This is a fatal error, and it stops the engine and informs application.

Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
This commit is contained in:
Seppo Takalo 2023-11-30 17:38:14 +02:00 committed by Maureen Helm
commit dc8f6da53c
9 changed files with 497 additions and 197 deletions

View file

@ -119,6 +119,10 @@ static void rd_client_event(struct lwm2m_ctx *client,
/* do nothing */
break;
case LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED:
LOG_DBG("LwM2M server disabled");
break;
case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE:
LOG_DBG("Bootstrap registration failure!");
break;

View file

@ -21,7 +21,7 @@ DEFINE_FFF_GLOBALS;
/* Maximum number of iterations within the state machine of RD Client
* service that is waited for until a possible event occurs
*/
static const uint8_t RD_CLIENT_MAX_LOOKUP_ITERATIONS = 100;
#define RD_CLIENT_MAX_LOOKUP_ITERATIONS 500
FAKE_VOID_FUNC(show_lwm2m_event, enum lwm2m_rd_client_event);
FAKE_VOID_FUNC(show_lwm2m_observe, enum lwm2m_observe_event);
@ -97,6 +97,9 @@ static void lwm2m_event_cb(struct lwm2m_ctx *client, enum lwm2m_rd_client_event
case LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF:
LOG_INF("*** LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF");
break;
case LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED:
LOG_INF("*** LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED");
break;
case LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED:
LOG_INF("*** LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED");
break;
@ -165,6 +168,7 @@ static void my_suite_before(void *data)
lwm2m_init_message_fake.custom_fake = lwm2m_init_message_fake_default;
coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_created;
coap_packet_append_option_fake.custom_fake = NULL;
stub_lwm2m_server_disable(false);
}
static void my_suite_after(void *data)
@ -198,8 +202,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_ok)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -207,6 +209,7 @@ ZTEST(lwm2m_rd_client, test_start_registration_ok)
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert(lwm2m_rd_client_ctx() == &ctx, "");
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
@ -228,8 +231,6 @@ ZTEST(lwm2m_rd_client, test_register_update_too_small_lifetime_to_default)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -237,6 +238,7 @@ ZTEST(lwm2m_rd_client, test_register_update_too_small_lifetime_to_default)
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert(lwm2m_rd_client_ctx() == &ctx, "");
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
@ -249,14 +251,13 @@ ZTEST(lwm2m_rd_client, test_timeout_resume_registration)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert(lwm2m_rd_client_ctx() == &ctx, "");
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
@ -273,16 +274,17 @@ ZTEST(lwm2m_rd_client, test_start_registration_timeout)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_timeout_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DISCONNECT), NULL);
test_prepare_pending_message_cb(&message_reply_timeout_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR), NULL);
}
ZTEST(lwm2m_rd_client, test_start_registration_fail)
@ -291,8 +293,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_fail)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -302,8 +302,15 @@ ZTEST(lwm2m_rd_client, test_start_registration_fail)
lwm2m_init_message_fake.custom_fake = lwm2m_init_message_fake_default;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE),
NULL);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE),
NULL);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE),
NULL);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR),
NULL);
}
ZTEST(lwm2m_rd_client, test_start_registration_update)
@ -312,8 +319,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_update)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -321,6 +326,7 @@ ZTEST(lwm2m_rd_client, test_start_registration_update)
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
@ -335,8 +341,6 @@ ZTEST(lwm2m_rd_client, test_rx_off)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -344,6 +348,7 @@ ZTEST(lwm2m_rd_client, test_rx_off)
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
@ -359,8 +364,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_update_fail)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -368,6 +371,7 @@ ZTEST(lwm2m_rd_client, test_start_registration_update_fail)
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
@ -384,8 +388,6 @@ ZTEST(lwm2m_rd_client, test_registration_update_timeout)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -393,6 +395,7 @@ ZTEST(lwm2m_rd_client, test_registration_update_timeout)
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
test_prepare_pending_message_cb(&message_reply_timeout_cb_default);
@ -415,8 +418,6 @@ ZTEST(lwm2m_rd_client, test_deregistration_timeout)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -424,6 +425,7 @@ ZTEST(lwm2m_rd_client, test_deregistration_timeout)
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
@ -439,8 +441,6 @@ ZTEST(lwm2m_rd_client, test_error_on_registration_update)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -449,6 +449,8 @@ ZTEST(lwm2m_rd_client, test_error_on_registration_update)
coap_packet_append_option_fake.custom_fake = NULL;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
@ -482,8 +484,6 @@ ZTEST(lwm2m_rd_client, test_suspend_resume_registration)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -491,6 +491,7 @@ ZTEST(lwm2m_rd_client, test_suspend_resume_registration)
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
zassert_true(!lwm2m_rd_client_is_suspended(&ctx), NULL);
@ -517,8 +518,6 @@ ZTEST(lwm2m_rd_client, test_suspend_stop_resume)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -527,6 +526,7 @@ ZTEST(lwm2m_rd_client, test_suspend_stop_resume)
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
zassert_true(lwm2m_rd_client_pause() == 0, NULL);
@ -544,8 +544,6 @@ ZTEST(lwm2m_rd_client, test_socket_error)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -554,6 +552,7 @@ ZTEST(lwm2m_rd_client, test_socket_error)
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
@ -569,8 +568,6 @@ ZTEST(lwm2m_rd_client, test_socket_error_on_stop)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -579,6 +576,7 @@ ZTEST(lwm2m_rd_client, test_socket_error_on_stop)
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
@ -608,8 +606,6 @@ ZTEST(lwm2m_rd_client, test_engine_trigger_bootstrap)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -617,6 +613,7 @@ ZTEST(lwm2m_rd_client, test_engine_trigger_bootstrap)
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_fake_true;
@ -638,8 +635,6 @@ ZTEST(lwm2m_rd_client, test_bootstrap_timeout)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_timeout_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -651,6 +646,7 @@ ZTEST(lwm2m_rd_client, test_bootstrap_timeout)
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 1, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_timeout_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE),
NULL);
}
@ -661,8 +657,6 @@ ZTEST(lwm2m_rd_client, test_bootstrap_fail)
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -674,20 +668,19 @@ ZTEST(lwm2m_rd_client, test_bootstrap_fail)
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 1, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE),
NULL);
}
ZTEST(lwm2m_rd_client, test_bootstrap_no_srv_fallback_to_register)
ZTEST(lwm2m_rd_client, test_bootstrap_no_srv)
{
struct lwm2m_ctx ctx;
(void)memset(&ctx, 0x0, sizeof(ctx));
test_prepare_pending_message_cb(&message_reply_cb_default);
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
@ -695,6 +688,134 @@ ZTEST(lwm2m_rd_client, test_bootstrap_no_srv_fallback_to_register)
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 1, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE),
NULL);
}
ZTEST(lwm2m_rd_client, test_disable_server)
{
struct lwm2m_ctx ctx;
(void)memset(&ctx, 0x0, sizeof(ctx));
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_deleted;
stub_lwm2m_server_disable(true);
lwm2m_rd_client_server_disabled(0);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED),
NULL);
}
ZTEST(lwm2m_rd_client, test_disable_server_stop)
{
struct lwm2m_ctx ctx;
(void)memset(&ctx, 0x0, sizeof(ctx));
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_deleted;
stub_lwm2m_server_disable(true);
lwm2m_rd_client_server_disabled(0);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED),
NULL);
wait_for_service(1);
zassert_true(lwm2m_rd_client_stop(&ctx, lwm2m_event_cb, true) == 0, NULL);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DISCONNECT), NULL);
}
ZTEST(lwm2m_rd_client, test_disable_server_connect)
{
struct lwm2m_ctx ctx;
(void)memset(&ctx, 0x0, sizeof(ctx));
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_deleted;
stub_lwm2m_server_disable(true);
lwm2m_rd_client_server_disabled(0);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED),
NULL);
wait_for_service(500);
coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_created;
stub_lwm2m_server_disable(false);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
}
ZTEST(lwm2m_rd_client, test_fallback_to_bootstrap)
{
struct lwm2m_ctx ctx;
(void)memset(&ctx, 0x0, sizeof(ctx));
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_fake_true;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_timeout_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE),
NULL);
}
ZTEST(lwm2m_rd_client, test_no_srv_fallback_to_bootstrap)
{
struct lwm2m_ctx ctx;
(void)memset(&ctx, 0x0, sizeof(ctx));
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_changed;
lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_fake_true;
stub_lwm2m_server_disable(true);
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_COMPLETE),
NULL);
coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_created;
coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok;
stub_lwm2m_server_disable(false);
engine_bootstrap_finish();
zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE),
NULL);
}

View file

@ -116,6 +116,24 @@ char *lwm2m_sprint_ip_addr_fake_default(const struct sockaddr *addr)
DEFINE_FAKE_VALUE_FUNC(int, lwm2m_server_short_id_to_inst, uint16_t);
DEFINE_FAKE_VALUE_FUNC(int, lwm2m_security_index_to_inst_id, int);
DEFINE_FAKE_VALUE_FUNC(int, lwm2m_security_short_id_to_inst, uint16_t);
DEFINE_FAKE_VALUE_FUNC(int, lwm2m_server_disable, uint16_t, k_timeout_t);
DEFINE_FAKE_VALUE_FUNC(uint8_t, lwm2m_server_get_prio, uint16_t);
DEFINE_FAKE_VOID_FUNC(lwm2m_server_reset_timestamps);
static bool srv_disabled;
bool lwm2m_server_select(uint16_t *obj_inst_id)
{
if (obj_inst_id) {
*obj_inst_id = 0;
}
return !srv_disabled;
}
void stub_lwm2m_server_disable(bool disable)
{
srv_disabled = disable;
}
k_work_handler_t service;
int64_t next;
@ -177,9 +195,13 @@ void test_lwm2m_engine_start_service(void)
void test_lwm2m_engine_stop_service(void)
{
struct k_work_sync sync;
pending_message_cb = NULL;
pending_message = NULL;
running = false;
k_work_cancel(&service_work);
k_work_flush(&service_work, &sync);
}
/* subsys/net/lib/lwm2m/lwm2m_message_handling.h */

View file

@ -59,6 +59,8 @@ DECLARE_FAKE_VALUE_FUNC(int, lwm2m_socket_close, struct lwm2m_ctx *);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_close_socket, struct lwm2m_ctx *);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_socket_suspend, struct lwm2m_ctx *);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_inst_id_to_index, uint16_t);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_short_id_to_inst, uint16_t);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_index_to_inst_id, int);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_engine_connection_resume, struct lwm2m_ctx *);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_push_queued_buffers, struct lwm2m_ctx *);
DECLARE_FAKE_VOID_FUNC(lwm2m_engine_context_init, struct lwm2m_ctx *);
@ -68,10 +70,15 @@ DECLARE_FAKE_VOID_FUNC(lwm2m_engine_context_close, struct lwm2m_ctx *);
DECLARE_FAKE_VALUE_FUNC(char *, lwm2m_sprint_ip_addr, const struct sockaddr *);
char *lwm2m_sprint_ip_addr_fake_default(const struct sockaddr *addr);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_server_short_id_to_inst, uint16_t);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_index_to_inst_id, int);
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_server_disable, uint16_t, k_timeout_t);
DECLARE_FAKE_VALUE_FUNC(uint8_t, lwm2m_server_get_prio, uint16_t);
DECLARE_FAKE_VOID_FUNC(lwm2m_server_reset_timestamps);
void wait_for_service(uint16_t cycles);
void test_lwm2m_engine_start_service(void);
void test_lwm2m_engine_stop_service(void);
void stub_lwm2m_server_disable(bool disable);
/* subsys/net/lib/lwm2m/lwm2m_message_handling.h */
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_init_message, struct lwm2m_message *);