1 /*
2  * Copyright (c) 2022 Rodrigo Peixoto <rodrigopex@gmail.com>
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #include <string.h>
7 
8 #include <zephyr/kernel.h>
9 #include <zephyr/logging/log.h>
10 #include <zephyr/sys/util_macro.h>
11 #include <zephyr/zbus/zbus.h>
12 #include <zephyr/ztest.h>
13 #include <zephyr/ztest_assert.h>
14 LOG_MODULE_DECLARE(zbus, CONFIG_ZBUS_LOG_LEVEL);
15 
16 struct version_msg {
17 	uint8_t major;
18 	uint8_t minor;
19 	uint16_t build;
20 };
21 
22 struct external_data_msg {
23 	void *reference;
24 	size_t size;
25 };
26 
27 ZBUS_CHAN_DEFINE(dyn_chan_no_subs,	   /* Name */
28 		 struct external_data_msg, /* Message type */
29 
30 		 NULL,		       /* Validator */
31 		 NULL,		       /* User data */
32 		 ZBUS_OBSERVERS_EMPTY, /* observers */
33 		 ZBUS_MSG_INIT(0)      /* Initial value {0} */
34 );
35 
36 ZBUS_CHAN_DEFINE(dyn_chan,		   /* Name */
37 		 struct external_data_msg, /* Message type */
38 
39 		 NULL,		     /* Validator */
40 		 NULL,		     /* User data */
41 		 ZBUS_OBSERVERS(s1), /* observers */
42 		 ZBUS_MSG_INIT(0)    /* Initial value {0} */
43 );
44 
45 static struct {
46 	uint8_t a;
47 	uint64_t b;
48 } my_random_data_expected;
49 
s1_cb(const struct zbus_channel * chan)50 static void s1_cb(const struct zbus_channel *chan)
51 {
52 	LOG_DBG("Callback called");
53 
54 	const struct external_data_msg *chan_message;
55 
56 	chan_message = zbus_chan_const_msg(chan);
57 	memcpy(&my_random_data_expected, chan_message->reference, sizeof(my_random_data_expected));
58 
59 	zbus_chan_finish(chan);
60 }
61 ZBUS_LISTENER_DEFINE(s1, s1_cb);
62 
63 /**
64  * @brief Test Asserts
65  *
66  * This test verifies various assert macros provided by ztest.
67  *
68  */
ZTEST(dynamic,test_static)69 ZTEST(dynamic, test_static)
70 {
71 	uint8_t static_memory[256] = {0};
72 	struct external_data_msg static_external_data = {.reference = static_memory, .size = 256};
73 
74 	struct {
75 		uint8_t a;
76 		uint64_t b;
77 	} my_random_data = {.a = 10, .b = 200000};
78 
79 	memcpy(static_memory, &my_random_data, sizeof(my_random_data));
80 
81 	int err = zbus_chan_pub(&dyn_chan, &static_external_data, K_MSEC(500));
82 
83 	zassert_equal(err, 0, "Allocation could not be performed");
84 
85 	k_msleep(1000);
86 
87 	zassert_equal(my_random_data.a, my_random_data_expected.a,
88 		      "It must be 10, random data is %d", my_random_data_expected.a);
89 	zassert_equal(my_random_data.b, my_random_data_expected.b, "It must be 200000");
90 
91 	struct external_data_msg edm = {0};
92 
93 	zbus_chan_read(&dyn_chan, &edm, K_NO_WAIT);
94 	zassert_equal(edm.reference, static_memory, "The pointer must be equal here");
95 }
96 
ZTEST(dynamic,test_malloc)97 ZTEST(dynamic, test_malloc)
98 {
99 	uint8_t *dynamic_memory = k_malloc(128);
100 
101 	zassert_not_equal(dynamic_memory, NULL, "Memory could not be allocated");
102 
103 	struct external_data_msg static_external_data = {.reference = dynamic_memory, .size = 128};
104 
105 	struct {
106 		uint8_t a;
107 		uint64_t b;
108 	} my_random_data = {.a = 20, .b = 300000};
109 
110 	memcpy(dynamic_memory, &my_random_data, sizeof(my_random_data));
111 
112 	int err = zbus_chan_pub(&dyn_chan, &static_external_data, K_NO_WAIT);
113 
114 	zassert_equal(err, 0, "Allocation could not be performed");
115 
116 	k_msleep(1000);
117 
118 	zassert_equal(my_random_data.a, my_random_data_expected.a, "It must be 20");
119 	zassert_equal(my_random_data.b, my_random_data_expected.b, "It must be 300000");
120 
121 	struct external_data_msg *actual_message_data = NULL;
122 
123 	err = zbus_chan_claim(&dyn_chan, K_NO_WAIT);
124 	zassert_equal(err, 0, "Could not claim the channel");
125 
126 	actual_message_data = (struct external_data_msg *)dyn_chan.message;
127 	zassert_equal(actual_message_data->reference, dynamic_memory,
128 		      "The pointer must be equal here");
129 
130 	k_free(actual_message_data->reference);
131 	actual_message_data->reference = NULL;
132 	actual_message_data->size = 0;
133 
134 	zbus_chan_finish(&dyn_chan);
135 
136 	struct external_data_msg expected_to_be_clean = {0};
137 
138 	zbus_chan_read(&dyn_chan, &expected_to_be_clean, K_NO_WAIT);
139 	zassert_equal(expected_to_be_clean.reference, NULL,
140 		      "The current message reference should be NULL");
141 	zassert_equal(expected_to_be_clean.size, 0, "The current message size should be zero");
142 }
143 
144 ZTEST_SUITE(dynamic, NULL, NULL, NULL, NULL, NULL);
145