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