1 /*
2 * Copyright (c) 2022 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #if defined(CONFIG_LIMITED_TEST)
8
9 #include <zephyr/ztest.h>
10 #include <zephyr/net_buf.h>
11 #include <zephyr/mgmt/mcumgr/mgmt/mgmt.h>
12 #include <zephyr/mgmt/mcumgr/transport/smp_dummy.h>
13 #include <zephyr/mgmt/mcumgr/mgmt/callbacks.h>
14 #include <zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h>
15 #include <os_mgmt_processor.h>
16 #include <zcbor_common.h>
17 #include <zcbor_decode.h>
18 #include <zcbor_encode.h>
19 #include <mgmt/mcumgr/util/zcbor_bulk.h>
20 #include <zephyr/version.h>
21 #include <string.h>
22 #include <smp_internal.h>
23 #include "smp_test_util.h"
24
25 #define SMP_RESPONSE_WAIT_TIME 3
26 #define ZCBOR_BUFFER_SIZE 64
27 #define OUTPUT_BUFFER_SIZE 64
28 #define ZCBOR_HISTORY_ARRAY_SIZE 4
29
30 static struct net_buf *nb;
31
32 /* Responses to commands */
33 const uint8_t response_kernel_name[] = "Zephyr";
34
35 const uint8_t query_kernel_name[] = "s";
36 const uint8_t query_all[] = "a";
37
ZTEST(os_mgmt_info_limited,test_info_1_kernel_name)38 ZTEST(os_mgmt_info_limited, test_info_1_kernel_name)
39 {
40 uint8_t buffer[ZCBOR_BUFFER_SIZE];
41 uint8_t buffer_out[OUTPUT_BUFFER_SIZE];
42 bool ok;
43 uint16_t buffer_size;
44 zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
45 zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
46 bool received;
47 struct zcbor_string output = { 0 };
48 size_t decoded = 0;
49
50 struct zcbor_map_decode_key_val output_decode[] = {
51 ZCBOR_MAP_DECODE_KEY_DECODER("output", zcbor_tstr_decode, &output),
52 };
53
54 memset(buffer, 0, sizeof(buffer));
55 memset(buffer_out, 0, sizeof(buffer_out));
56 buffer_size = 0;
57 memset(zse, 0, sizeof(zse));
58 memset(zsd, 0, sizeof(zsd));
59
60 zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0);
61
62 ok = create_mcumgr_format_packet(zse, query_kernel_name, buffer, buffer_out, &buffer_size);
63 zassert_true(ok, "Expected packet creation to be successful\n");
64
65 /* Enable dummy SMP backend and ready for usage */
66 smp_dummy_enable();
67 smp_dummy_clear_state();
68
69 /* Send query command to dummy SMP backend */
70 (void)smp_dummy_tx_pkt(buffer_out, buffer_size);
71 smp_dummy_add_data();
72
73 /* For a short duration to see if response has been received */
74 received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME);
75
76 zassert_true(received, "Expected to receive data but timed out\n");
77
78 /* Retrieve response buffer and ensure validity */
79 nb = smp_dummy_get_outgoing();
80 smp_dummy_disable();
81
82 /* Process received data by removing header */
83 (void)net_buf_pull(nb, sizeof(struct smp_hdr));
84 zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0);
85
86 ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0;
87
88 zassert_true(ok, "Expected decode to be successful\n");
89 zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element\n");
90
91 zassert_equal((sizeof(response_kernel_name) - 1), output.len,
92 "Expected to receive %d bytes but got %d\n",
93 (sizeof(response_kernel_name) - 1), output.len);
94
95 zassert_mem_equal(response_kernel_name, output.value, output.len,
96 "Expected received data mismatch");
97 }
98
ZTEST(os_mgmt_info_limited,test_info_2_all)99 ZTEST(os_mgmt_info_limited, test_info_2_all)
100 {
101 uint8_t buffer[ZCBOR_BUFFER_SIZE];
102 uint8_t buffer_out[OUTPUT_BUFFER_SIZE];
103 bool ok;
104 uint16_t buffer_size;
105 zcbor_state_t zse[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
106 zcbor_state_t zsd[ZCBOR_HISTORY_ARRAY_SIZE] = { 0 };
107 bool received;
108 struct zcbor_string output = { 0 };
109 size_t decoded = 0;
110 int32_t rc;
111
112 struct zcbor_map_decode_key_val output_decode[] = {
113 ZCBOR_MAP_DECODE_KEY_DECODER("output", zcbor_tstr_decode, &output),
114 };
115
116 struct zcbor_map_decode_key_val error_decode[] = {
117 ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &rc),
118 };
119
120 memset(buffer, 0, sizeof(buffer));
121 memset(buffer_out, 0, sizeof(buffer_out));
122 buffer_size = 0;
123 memset(zse, 0, sizeof(zse));
124 memset(zsd, 0, sizeof(zsd));
125
126 zcbor_new_encode_state(zse, 2, buffer, ARRAY_SIZE(buffer), 0);
127
128 ok = create_mcumgr_format_packet(zse, query_all, buffer, buffer_out, &buffer_size);
129 zassert_true(ok, "Expected packet creation to be successful\n");
130
131 /* Enable dummy SMP backend and ready for usage */
132 smp_dummy_enable();
133 smp_dummy_clear_state();
134
135 /* Send query command to dummy SMP backend */
136 (void)smp_dummy_tx_pkt(buffer_out, buffer_size);
137 smp_dummy_add_data();
138
139 /* For a short duration to see if response has been received */
140 received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME);
141
142 zassert_true(received, "Expected to receive data but timed out\n");
143
144 /* Retrieve response buffer and ensure validity */
145 nb = smp_dummy_get_outgoing();
146 smp_dummy_disable();
147
148 /* Process received data by removing header */
149 (void)net_buf_pull(nb, sizeof(struct smp_hdr));
150 zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0);
151
152 /* Ensure only an error is received */
153 ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0;
154
155 zassert_true(ok, "Expected decode to be successful\n");
156 zassert_equal(decoded, 0, "Expected to receive 0 decoded zcbor element\n");
157
158 zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0);
159 ok = zcbor_map_decode_bulk(zsd, error_decode, ARRAY_SIZE(error_decode), &decoded) == 0;
160
161 zassert_true(ok, "Expected decode to be successful\n");
162 zassert_equal(decoded, 1, "Expected to receive 1 decoded zcbor element\n");
163 zassert_equal(output.len, 0, "Expected to receive 0 bytes but got %d\n", output.len);
164 zassert_equal(rc, MGMT_ERR_EMSGSIZE, "Expected to receive EMSGSIZE error but got %d\n",
165 rc);
166 }
167
cleanup_test(void * p)168 static void cleanup_test(void *p)
169 {
170 if (nb != NULL) {
171 net_buf_unref(nb);
172 nb = NULL;
173 }
174 }
175
176 /* Limited size buffer test set */
177 ZTEST_SUITE(os_mgmt_info_limited, NULL, NULL, NULL, cleanup_test, NULL);
178
179 #endif
180