| /* |
| * Copyright (c) 2023 Nordic Semiconductor ASA |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <zephyr/ztest.h> |
| #include <zephyr/net/buf.h> |
| #include <zephyr/mgmt/mcumgr/mgmt/mgmt.h> |
| #include <zephyr/mgmt/mcumgr/transport/smp_dummy.h> |
| #include <zephyr/mgmt/mcumgr/mgmt/callbacks.h> |
| #include <zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h> |
| #include <zcbor_common.h> |
| #include <zcbor_decode.h> |
| #include <zcbor_encode.h> |
| #include <mgmt/mcumgr/util/zcbor_bulk.h> |
| #include <version.h> |
| #include <string.h> |
| #include <smp_internal.h> |
| #include "smp_test_util.h" |
| |
| #define SMP_RESPONSE_WAIT_TIME 3 |
| #define ZCBOR_BUFFER_SIZE 64 |
| #define OUTPUT_BUFFER_SIZE 64 |
| #define ZCBOR_HISTORY_ARRAY_SIZE 4 |
| |
| /* Test sets */ |
| enum { |
| CB_NOTIFICATION_TEST_CALLBACK_DISABLED, |
| CB_NOTIFICATION_TEST_CALLBACK_ENABLED, |
| CB_NOTIFICATION_TEST_CALLBACK_DISABLED_VERIFY, |
| |
| CB_NOTIFICATION_TEST_SET_COUNT |
| }; |
| |
| static struct net_buf *nb; |
| |
| struct state { |
| uint8_t test_set; |
| }; |
| |
| static struct state test_state = { |
| .test_set = 0, |
| }; |
| |
| static bool cmd_recv_got; |
| static bool cmd_status_got; |
| static bool cmd_done_got; |
| static bool cmd_other_got; |
| |
| /* Responses to commands */ |
| |
| static int32_t mgmt_event_cmd_callback(uint32_t event, int32_t rc, bool *abort_more, |
| void *data, size_t data_size) |
| { |
| if (event == MGMT_EVT_OP_CMD_RECV) { |
| cmd_recv_got = true; |
| } else if (event == MGMT_EVT_OP_CMD_STATUS) { |
| cmd_status_got = true; |
| } else if (event == MGMT_EVT_OP_CMD_DONE) { |
| cmd_done_got = true; |
| } else { |
| cmd_other_got = true; |
| } |
| |
| return MGMT_ERR_EOK; |
| } |
| |
| static struct mgmt_callback mgmt_event_callback = { |
| .callback = mgmt_event_cmd_callback, |
| .event_id = (MGMT_EVT_OP_CMD_RECV | MGMT_EVT_OP_CMD_STATUS | MGMT_EVT_OP_CMD_DONE), |
| }; |
| |
| static void *setup_callbacks(void) |
| { |
| mgmt_callback_register(&mgmt_event_callback); |
| return NULL; |
| } |
| |
| static void destroy_callbacks(void *p) |
| { |
| mgmt_callback_unregister(&mgmt_event_callback); |
| } |
| |
| ZTEST(callback_disabled, test_notifications_disabled) |
| { |
| uint8_t buffer[ZCBOR_BUFFER_SIZE]; |
| uint8_t buffer_out[OUTPUT_BUFFER_SIZE]; |
| bool ok; |
| uint16_t buffer_size; |
| zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; |
| zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; |
| bool received; |
| |
| memset(buffer, 0, sizeof(buffer)); |
| memset(buffer_out, 0, sizeof(buffer_out)); |
| buffer_size = 0; |
| memset(zse, 0, sizeof(zse)); |
| memset(zsd, 0, sizeof(zsd)); |
| |
| zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0); |
| |
| ok = create_mcumgr_format_packet(zse, buffer, buffer_out, &buffer_size); |
| zassert_true(ok, "Expected packet creation to be successful\n"); |
| |
| /* Enable dummy SMP backend and ready for usage */ |
| smp_dummy_enable(); |
| smp_dummy_clear_state(); |
| |
| /* Send query command to dummy SMP backend */ |
| (void)smp_dummy_tx_pkt(buffer_out, buffer_size); |
| smp_dummy_add_data(); |
| |
| /* For a short duration to see if response has been received */ |
| received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); |
| |
| zassert_true(received, "Expected to receive data but timed out\n"); |
| |
| /* Retrieve response buffer */ |
| nb = smp_dummy_get_outgoing(); |
| smp_dummy_disable(); |
| |
| /* Check events */ |
| zassert_false(cmd_recv_got, "Did not expect received command callback\n"); |
| zassert_false(cmd_status_got, "Did not expect IMG status callback\n"); |
| zassert_false(cmd_done_got, "Did not expect done command callback\n"); |
| zassert_false(cmd_other_got, "Did not expect other callback(s)\n"); |
| } |
| |
| ZTEST(callback_enabled, test_notifications_enabled) |
| { |
| uint8_t buffer[ZCBOR_BUFFER_SIZE]; |
| uint8_t buffer_out[OUTPUT_BUFFER_SIZE]; |
| bool ok; |
| uint16_t buffer_size; |
| zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; |
| zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; |
| bool received; |
| |
| memset(buffer, 0, sizeof(buffer)); |
| memset(buffer_out, 0, sizeof(buffer_out)); |
| buffer_size = 0; |
| memset(zse, 0, sizeof(zse)); |
| memset(zsd, 0, sizeof(zsd)); |
| |
| zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0); |
| |
| ok = create_mcumgr_format_packet(zse, buffer, buffer_out, &buffer_size); |
| zassert_true(ok, "Expected packet creation to be successful\n"); |
| |
| /* Enable dummy SMP backend and ready for usage */ |
| smp_dummy_enable(); |
| smp_dummy_clear_state(); |
| |
| /* Send query command to dummy SMP backend */ |
| (void)smp_dummy_tx_pkt(buffer_out, buffer_size); |
| smp_dummy_add_data(); |
| |
| /* For a short duration to see if response has been received */ |
| received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); |
| |
| zassert_true(received, "Expected to receive data but timed out\n"); |
| |
| /* Retrieve response buffer */ |
| nb = smp_dummy_get_outgoing(); |
| smp_dummy_disable(); |
| |
| /* Check events */ |
| zassert_true(cmd_recv_got, "Expected received command callback\n"); |
| zassert_false(cmd_status_got, "Did not expect IMG status callback\n"); |
| zassert_true(cmd_done_got, "Expected done command callback\n"); |
| zassert_false(cmd_other_got, "Did not expect other callback(s)\n"); |
| } |
| |
| ZTEST(callback_disabled_verify, test_notifications_disabled_verify) |
| { |
| uint8_t buffer[ZCBOR_BUFFER_SIZE]; |
| uint8_t buffer_out[OUTPUT_BUFFER_SIZE]; |
| bool ok; |
| uint16_t buffer_size; |
| zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; |
| zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 }; |
| bool received; |
| |
| memset(buffer, 0, sizeof(buffer)); |
| memset(buffer_out, 0, sizeof(buffer_out)); |
| buffer_size = 0; |
| memset(zse, 0, sizeof(zse)); |
| memset(zsd, 0, sizeof(zsd)); |
| |
| zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0); |
| |
| ok = create_mcumgr_format_packet(zse, buffer, buffer_out, &buffer_size); |
| zassert_true(ok, "Expected packet creation to be successful\n"); |
| |
| /* Enable dummy SMP backend and ready for usage */ |
| smp_dummy_enable(); |
| smp_dummy_clear_state(); |
| |
| /* Send query command to dummy SMP backend */ |
| (void)smp_dummy_tx_pkt(buffer_out, buffer_size); |
| smp_dummy_add_data(); |
| |
| /* For a short duration to see if response has been received */ |
| received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME); |
| |
| zassert_true(received, "Expected to receive data but timed out\n"); |
| |
| /* Retrieve response buffer */ |
| nb = smp_dummy_get_outgoing(); |
| smp_dummy_disable(); |
| |
| /* Check events */ |
| zassert_false(cmd_recv_got, "Did not expect received command callback\n"); |
| zassert_false(cmd_status_got, "Did not expect IMG status callback\n"); |
| zassert_false(cmd_done_got, "Did not expect done command callback\n"); |
| zassert_false(cmd_other_got, "Did not expect other callback(s)\n"); |
| } |
| |
| static void cleanup_test(void *p) |
| { |
| if (nb != NULL) { |
| net_buf_unref(nb); |
| nb = NULL; |
| } |
| |
| cmd_recv_got = false; |
| cmd_status_got = false; |
| cmd_done_got = false; |
| cmd_other_got = false; |
| } |
| |
| void test_main(void) |
| { |
| while (test_state.test_set < CB_NOTIFICATION_TEST_SET_COUNT) { |
| ztest_run_all(&test_state); |
| ++test_state.test_set; |
| } |
| |
| ztest_verify_all_test_suites_ran(); |
| } |
| |
| static bool callback_disabled_predicate(const void *state) |
| { |
| return ((struct state *)state)->test_set == CB_NOTIFICATION_TEST_CALLBACK_DISABLED; |
| } |
| |
| static bool callback_enabled_predicate(const void *state) |
| { |
| return ((struct state *)state)->test_set == CB_NOTIFICATION_TEST_CALLBACK_ENABLED; |
| } |
| |
| static bool callback_disabled_verify_predicate(const void *state) |
| { |
| return ((struct state *)state)->test_set == CB_NOTIFICATION_TEST_CALLBACK_DISABLED_VERIFY; |
| } |
| |
| ZTEST_SUITE(callback_disabled, callback_disabled_predicate, NULL, NULL, cleanup_test, NULL); |
| ZTEST_SUITE(callback_enabled, callback_enabled_predicate, setup_callbacks, NULL, cleanup_test, |
| destroy_callbacks); |
| ZTEST_SUITE(callback_disabled_verify, callback_disabled_verify_predicate, NULL, NULL, |
| cleanup_test, NULL); |