1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/ztest.h>
8 
9 #include "lwm2m_engine.h"
10 #include "lwm2m_util.h"
11 
12 #define TEST_OBJ_ID 32768
13 
14 static uint32_t callback_checker;
15 static char pre_write_cb_buf[10];
16 
pre_write_cb(uint16_t obj_inst_id,uint16_t res_id,uint16_t res_inst_id,size_t * data_len)17 static void *pre_write_cb(uint16_t obj_inst_id,
18 			  uint16_t res_id,
19 			  uint16_t res_inst_id,
20 			  size_t *data_len)
21 {
22 	callback_checker |= 0x01;
23 	return pre_write_cb_buf;
24 }
25 
post_write_cb(uint16_t obj_inst_id,uint16_t res_id,uint16_t res_inst_id,uint8_t * data,uint16_t data_len,bool last_block,size_t total_size,size_t offset)26 static int post_write_cb(uint16_t obj_inst_id, uint16_t res_id,
27 			 uint16_t res_inst_id, uint8_t *data,
28 			 uint16_t data_len, bool last_block,
29 			 size_t total_size, size_t offset)
30 {
31 	callback_checker |= 0x02;
32 	return 0;
33 }
34 
read_cb(uint16_t obj_inst_id,uint16_t res_id,uint16_t res_inst_id,size_t * data_len)35 static void *read_cb(uint16_t obj_inst_id,
36 		     uint16_t res_id,
37 		     uint16_t res_inst_id,
38 		     size_t *data_len)
39 {
40 	callback_checker |= 0x04;
41 	return 0;
42 }
43 
validate_cb(uint16_t obj_inst_id,uint16_t res_id,uint16_t res_inst_id,uint8_t * data,uint16_t data_len,bool last_block,size_t total_size,size_t offset)44 static int validate_cb(uint16_t obj_inst_id, uint16_t res_id,
45 		       uint16_t res_inst_id, uint8_t *data, uint16_t data_len,
46 		       bool last_block, size_t total_size, size_t offset)
47 {
48 	callback_checker |= 0x08;
49 	return 0;
50 }
51 
obj_create_cb(uint16_t obj_inst_id)52 static int obj_create_cb(uint16_t obj_inst_id)
53 {
54 	callback_checker |= 0x10;
55 	return 0;
56 }
57 
obj_delete_cb(uint16_t obj_inst_id)58 static int obj_delete_cb(uint16_t obj_inst_id)
59 {
60 	callback_checker |= 0x20;
61 	return 0;
62 }
63 
exec_cb(uint16_t obj_inst_id,uint8_t * args,uint16_t args_len)64 static int exec_cb(uint16_t obj_inst_id, uint8_t *args, uint16_t args_len)
65 {
66 	callback_checker |= 0x40;
67 	return 0;
68 }
69 
70 ZTEST_SUITE(lwm2m_registry, NULL, NULL, NULL, NULL, NULL);
71 
ZTEST(lwm2m_registry,test_object_creation_and_deletion)72 ZTEST(lwm2m_registry, test_object_creation_and_deletion)
73 {
74 	int ret;
75 
76 	ret = lwm2m_create_object_inst(&LWM2M_OBJ(3303, 0));
77 	zassert_equal(ret, 0);
78 
79 	ret = lwm2m_delete_object_inst(&LWM2M_OBJ(3303, 0));
80 	zassert_equal(ret, 0);
81 }
82 
ZTEST(lwm2m_registry,test_create_unknown_object)83 ZTEST(lwm2m_registry, test_create_unknown_object)
84 {
85 	int ret;
86 
87 	ret = lwm2m_create_object_inst(&LWM2M_OBJ(49999, 0));
88 	zassert_equal(ret, -ENOENT);
89 }
90 
ZTEST(lwm2m_registry,test_resource_buf)91 ZTEST(lwm2m_registry, test_resource_buf)
92 {
93 	int ret;
94 	uint8_t resource_buf = 0;
95 
96 	ret = lwm2m_create_object_inst(&LWM2M_OBJ(3303, 0));
97 	zassert_equal(ret, 0);
98 
99 	ret = lwm2m_set_res_buf(&LWM2M_OBJ(3303, 0, 6042), &resource_buf, sizeof(resource_buf),
100 				sizeof(resource_buf), 0);
101 	zassert_equal(ret, 0);
102 
103 	ret = lwm2m_set_u8(&LWM2M_OBJ(3303, 0, 6042), 0x5A);
104 	zassert_equal(ret, 0);
105 
106 	zassert_equal(resource_buf, 0x5A);
107 
108 	ret = lwm2m_delete_object_inst(&LWM2M_OBJ(3303, 0));
109 	zassert_equal(ret, 0);
110 }
111 
ZTEST(lwm2m_registry,test_unknown_res)112 ZTEST(lwm2m_registry, test_unknown_res)
113 {
114 	int ret;
115 	uint8_t resource_buf = 0;
116 
117 	ret = lwm2m_create_object_inst(&LWM2M_OBJ(3303, 0));
118 	zassert_equal(ret, 0);
119 
120 	ret = lwm2m_set_res_buf(&LWM2M_OBJ(3303, 0, 49999), &resource_buf, sizeof(resource_buf),
121 				sizeof(resource_buf), 0);
122 	zassert_equal(ret, -ENOENT);
123 
124 	ret = lwm2m_delete_object_inst(&LWM2M_OBJ(3303, 0));
125 	zassert_equal(ret, 0);
126 }
127 
ZTEST(lwm2m_registry,test_get_res_inst)128 ZTEST(lwm2m_registry, test_get_res_inst)
129 {
130 	zassert_is_null(lwm2m_engine_get_res_inst(&LWM2M_OBJ(3)));
131 	zassert_is_null(lwm2m_engine_get_res_inst(&LWM2M_OBJ(3, 0)));
132 	zassert_is_null(lwm2m_engine_get_res_inst(&LWM2M_OBJ(3, 0, 11)));
133 	zassert_not_null(lwm2m_engine_get_res_inst(&LWM2M_OBJ(3, 0, 11, 0)));
134 }
135 
ZTEST(lwm2m_registry,test_get_set)136 ZTEST(lwm2m_registry, test_get_set)
137 {
138 	bool b = true;
139 	uint8_t opaque[] = {0xde, 0xad, 0xbe, 0xff, 0, 0};
140 	char string[] = "Hello";
141 	uint8_t u8 = 8;
142 	int8_t s8 = -8;
143 	uint16_t u16 = 16;
144 	int16_t s16 = -16;
145 	uint32_t u32 = 32;
146 	int32_t s32 = -32;
147 	int64_t s64 = -64;
148 	time_t t = 1687949519;
149 	double d = 3.1415;
150 	double d2;
151 	struct lwm2m_objlnk objl = {.obj_id = 1, .obj_inst = 2};
152 	uint16_t l = sizeof(opaque);
153 
154 	zassert_equal(lwm2m_set_bool(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_BOOL), b), 0);
155 	zassert_equal(lwm2m_set_opaque(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_OPAQUE), opaque, l), 0);
156 	zassert_equal(lwm2m_set_string(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_STRING), string), 0);
157 	zassert_equal(lwm2m_set_u8(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_U8), u8), 0);
158 	zassert_equal(lwm2m_set_s8(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_S8), s8), 0);
159 	zassert_equal(lwm2m_set_u16(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_U16), u16), 0);
160 	zassert_equal(lwm2m_set_s16(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_S16), s16), 0);
161 	zassert_equal(lwm2m_set_u32(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_U32), u32), 0);
162 	zassert_equal(lwm2m_set_s32(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_S32), s32), 0);
163 	zassert_equal(lwm2m_set_s64(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_S64), s64), 0);
164 	zassert_equal(lwm2m_set_time(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_TIME), t), 0);
165 	zassert_equal(lwm2m_set_f64(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_FLOAT), d), 0);
166 	zassert_equal(lwm2m_set_objlnk(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_OBJLNK), &objl), 0);
167 
168 	zassert_equal(lwm2m_get_bool(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_BOOL), &b), 0);
169 	zassert_equal(lwm2m_get_opaque(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_OPAQUE), &opaque, l), 0);
170 	zassert_equal(lwm2m_get_string(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_STRING), &string, l), 0);
171 	zassert_equal(lwm2m_get_u8(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_U8), &u8), 0);
172 	zassert_equal(lwm2m_get_s8(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_S8), &s8), 0);
173 	zassert_equal(lwm2m_get_u16(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_U16), &u16), 0);
174 	zassert_equal(lwm2m_get_s16(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_S16), &s16), 0);
175 	zassert_equal(lwm2m_get_u32(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_U32), &u32), 0);
176 	zassert_equal(lwm2m_get_s32(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_S32), &s32), 0);
177 	zassert_equal(lwm2m_get_s64(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_S64), &s64), 0);
178 	zassert_equal(lwm2m_get_time(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_TIME), &t), 0);
179 	zassert_equal(lwm2m_get_f64(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_FLOAT), &d2), 0);
180 	zassert_equal(lwm2m_get_objlnk(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_OBJLNK), &objl), 0);
181 
182 	zassert_equal(b, true);
183 	zassert_equal(memcmp(opaque, &(uint8_t[6]) {0xde, 0xad, 0xbe, 0xff, 0, 0}, l), 0);
184 	zassert_str_equal(string, "Hello");
185 	zassert_equal(u8, 8);
186 	zassert_equal(s8, -8);
187 	zassert_equal(u16, 16);
188 	zassert_equal(s16, -16);
189 	zassert_equal(u32, 32);
190 	zassert_equal(s32, -32);
191 	zassert_equal(s64, -64);
192 	zassert_equal(t, 1687949519);
193 	zassert_equal(d, d2);
194 	zassert_equal(
195 		memcmp(&objl, &(struct lwm2m_objlnk){.obj_id = 1, .obj_inst = 2}, sizeof(objl)), 0);
196 
197 	zassert_equal(lwm2m_set_res_data_len(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_STRING), 0), 0);
198 	char buf[10];
199 
200 	zassert_equal(
201 		lwm2m_get_string(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_STRING), buf, sizeof(buf)), 0);
202 	zassert_equal(strlen(buf), 0);
203 }
204 
ZTEST(lwm2m_registry,test_temp_sensor)205 ZTEST(lwm2m_registry, test_temp_sensor)
206 {
207 	int ret;
208 	uint8_t u8_buf = 0;
209 	time_t time_buf = 0;
210 	double dbl_buf = 0;
211 	char char_buf[10];
212 
213 	uint8_t u8_getbuf = 0;
214 	time_t time_getbuf = 0;
215 	double dbl_getbuf = 0;
216 	char char_getbuf[10];
217 
218 	ret = lwm2m_create_object_inst(&LWM2M_OBJ(3303, 0));
219 	zassert_equal(ret, 0);
220 
221 	ret = lwm2m_set_res_buf(&LWM2M_OBJ(3303, 0, 6042), &u8_buf, sizeof(u8_buf),
222 				sizeof(u8_buf), 0);
223 	zassert_equal(ret, 0);
224 	ret = lwm2m_set_res_buf(&LWM2M_OBJ(3303, 0, 5518), &time_buf, sizeof(time_buf),
225 				sizeof(time_buf), 0);
226 	zassert_equal(ret, 0);
227 	ret = lwm2m_set_res_buf(&LWM2M_OBJ(3303, 0, 5601), &dbl_buf, sizeof(dbl_buf),
228 				sizeof(dbl_buf), 0);
229 	zassert_equal(ret, 0);
230 	ret = lwm2m_set_res_buf(&LWM2M_OBJ(3303, 0, 5701), &char_buf, sizeof(char_buf),
231 				sizeof(char_buf), 0);
232 	zassert_equal(ret, 0);
233 
234 	ret = lwm2m_set_u8(&LWM2M_OBJ(3303, 0, 6042), 0x5A);
235 	zassert_equal(ret, 0);
236 	ret = lwm2m_set_time(&LWM2M_OBJ(3303, 0, 5518), 1674118825);
237 	zassert_equal(ret, 0);
238 	ret = lwm2m_set_f64(&LWM2M_OBJ(3303, 0, 5601), 5.89);
239 	zassert_equal(ret, 0);
240 	ret = lwm2m_set_string(&LWM2M_OBJ(3303, 0, 5701), "test");
241 	zassert_equal(ret, 0);
242 
243 	zassert_equal(u8_buf, 0x5A);
244 	zassert_equal(time_buf, 1674118825);
245 	zassert_within(dbl_buf, 5.89, 0.01);
246 	zassert_equal(strncmp(char_buf, "test", 10), 0);
247 
248 	ret = lwm2m_get_u8(&LWM2M_OBJ(3303, 0, 6042), &u8_getbuf);
249 	zassert_equal(ret, 0);
250 	ret = lwm2m_get_time(&LWM2M_OBJ(3303, 0, 5518), &time_getbuf);
251 	zassert_equal(ret, 0);
252 	ret = lwm2m_get_f64(&LWM2M_OBJ(3303, 0, 5601), &dbl_getbuf);
253 	zassert_equal(ret, 0);
254 	ret = lwm2m_get_string(&LWM2M_OBJ(3303, 0, 5701), &char_getbuf, 10);
255 	zassert_equal(ret, 0);
256 
257 	zassert_equal(u8_buf, u8_getbuf);
258 	zassert_equal(time_buf, time_getbuf);
259 	zassert_within(dbl_buf, dbl_getbuf, 0.01);
260 	zassert_equal(strncmp(char_buf, char_getbuf, 10), 0);
261 
262 	ret = lwm2m_delete_object_inst(&LWM2M_OBJ(3303, 0));
263 	zassert_equal(ret, 0);
264 }
265 
ZTEST(lwm2m_registry,test_resource_instance_creation_and_deletion)266 ZTEST(lwm2m_registry, test_resource_instance_creation_and_deletion)
267 {
268 	int ret;
269 
270 	ret = lwm2m_create_res_inst(&LWM2M_OBJ(4, 0, 1, 0));
271 	zassert_equal(ret, 0);
272 
273 	ret = lwm2m_delete_res_inst(&LWM2M_OBJ(4, 0, 1, 0));
274 	zassert_equal(ret, 0);
275 }
276 
ZTEST(lwm2m_registry,test_resource_instance_strings)277 ZTEST(lwm2m_registry, test_resource_instance_strings)
278 {
279 	int ret;
280 	char buf[256] = {0};
281 	static const char string_a[] = "Hello";
282 	static const char string_b[] = "World";
283 	struct lwm2m_obj_path path_a = LWM2M_OBJ(16, 0, 0, 0);
284 	struct lwm2m_obj_path path_b = LWM2M_OBJ(16, 0, 0, 1);
285 
286 	ret = lwm2m_create_object_inst(&LWM2M_OBJ(16, 0));
287 	zassert_equal(ret, 0);
288 
289 	ret = lwm2m_create_res_inst(&path_a);
290 	zassert_equal(ret, 0);
291 
292 	ret = lwm2m_create_res_inst(&path_b);
293 	zassert_equal(ret, 0);
294 
295 	ret = lwm2m_set_string(&path_a, string_a);
296 	zassert_equal(ret, 0);
297 
298 	ret = lwm2m_set_string(&path_b, string_b);
299 	zassert_equal(ret, 0);
300 
301 	ret = lwm2m_get_string(&path_a, buf, sizeof(buf));
302 	zassert_equal(ret, 0);
303 	zassert_equal(0, memcmp(buf, string_a, sizeof(string_a)));
304 
305 	ret = lwm2m_get_string(&path_b, buf, sizeof(buf));
306 	zassert_equal(ret, 0);
307 	zassert_equal(0, memcmp(buf, string_b, sizeof(string_b)));
308 
309 	ret = lwm2m_delete_object_inst(&LWM2M_OBJ(16, 0));
310 	zassert_equal(ret, 0);
311 }
312 
ZTEST(lwm2m_registry,test_callbacks)313 ZTEST(lwm2m_registry, test_callbacks)
314 {
315 	int ret;
316 	double sensor_val;
317 	struct lwm2m_engine_res *exec_res;
318 
319 	callback_checker = 0;
320 	ret = lwm2m_register_create_callback(3303, obj_create_cb);
321 	zassert_equal(ret, 0);
322 	lwm2m_register_delete_callback(3303, obj_delete_cb);
323 	zassert_equal(ret, 0);
324 
325 	ret = lwm2m_create_object_inst(&LWM2M_OBJ(3303, 0));
326 	zassert_equal(ret, 0);
327 	zassert_equal(callback_checker, 0x10);
328 
329 	ret = lwm2m_register_exec_callback(&LWM2M_OBJ(3303, 0, 5605), exec_cb);
330 	zassert_equal(ret, 0);
331 	ret = lwm2m_register_read_callback(&LWM2M_OBJ(3303, 0, 5700), read_cb);
332 	zassert_equal(ret, 0);
333 	ret = lwm2m_register_validate_callback(&LWM2M_OBJ(3303, 0, 5701), validate_cb);
334 	zassert_equal(ret, 0);
335 	ret = lwm2m_register_pre_write_callback(&LWM2M_OBJ(3303, 0, 5701), pre_write_cb);
336 	zassert_equal(ret, 0);
337 	ret = lwm2m_register_post_write_callback(&LWM2M_OBJ(3303, 0, 5701), post_write_cb);
338 	zassert_equal(ret, 0);
339 
340 	exec_res = lwm2m_engine_get_res(&LWM2M_OBJ(3303, 0, 5605));
341 	exec_res->execute_cb(0, 0, 0);
342 
343 	ret = lwm2m_set_string(&LWM2M_OBJ(3303, 0, 5701), "test");
344 	zassert_equal(ret, 0);
345 	zassert_equal(callback_checker, 0x5B);
346 
347 	ret = lwm2m_get_f64(&LWM2M_OBJ(3303, 0, 5700), &sensor_val);
348 	zassert_equal(ret, 0);
349 	zassert_equal(callback_checker, 0x5F);
350 
351 	ret = lwm2m_delete_object_inst(&LWM2M_OBJ(3303, 0));
352 	zassert_equal(ret, 0);
353 	zassert_equal(callback_checker, 0x7F);
354 }
355 
ZTEST(lwm2m_registry,test_strings)356 ZTEST(lwm2m_registry, test_strings)
357 {
358 	int ret;
359 	char buf[256] = {0};
360 	struct lwm2m_obj_path path = LWM2M_OBJ(0, 0, 0);
361 	static const char uri[] = "coap://127.0.0.1";
362 	uint16_t len;
363 	uint8_t *p;
364 
365 	ret = lwm2m_get_res_buf(&path, (void **)&p, &len, NULL, NULL);
366 	zassert_equal(ret, 0);
367 	memset(p, 0xff, len); /* Pre-fill buffer to check */
368 
369 	/* Handle strings in string resources */
370 	ret = lwm2m_set_string(&path, uri);
371 	zassert_equal(ret, 0);
372 	ret = lwm2m_get_res_buf(&path, (void **)&p, NULL, &len, NULL);
373 	zassert_equal(ret, 0);
374 	zassert_equal(len, sizeof(uri));
375 	zassert_equal(p[len - 1], '\0'); /* string terminator in buffer */
376 	zassert_equal(p[len], 0xff);
377 
378 	ret = lwm2m_get_string(&path, buf, sizeof(buf));
379 	zassert_equal(ret, 0);
380 	zassert_equal(memcmp(uri, buf, sizeof(uri)), 0);
381 	ret = lwm2m_get_string(&path, buf, sizeof(uri));
382 	zassert_equal(ret, 0);
383 	ret = lwm2m_get_string(&path, buf, strlen(uri));
384 	zassert_equal(ret, -ENOMEM);
385 
386 	/* Handle strings in opaque resources (no terminator) */
387 	path = LWM2M_OBJ(0, 0, 3);
388 	ret = lwm2m_get_res_buf(&path, (void **)&p, &len, NULL, NULL);
389 	zassert_equal(ret, 0);
390 	memset(p, 0xff, len); /* Pre-fill buffer to check */
391 
392 	ret = lwm2m_set_string(&path, uri);
393 	zassert_equal(ret, 0);
394 	ret = lwm2m_get_res_buf(&path, (void **)&p, NULL, &len, NULL);
395 	zassert_equal(ret, 0);
396 	zassert_equal(len, strlen(uri)); /* No terminator counted in data length */
397 	zassert_equal(p[len - 1], '1'); /* Last character in buffer is not terminator */
398 	zassert_equal(p[len], 0xff);
399 	memset(buf, 0xff, sizeof(buf));
400 	ret = lwm2m_get_string(&path, buf, sizeof(buf)); /* get_string ensures termination */
401 	zassert_equal(ret, 0);
402 	zassert_equal(memcmp(uri, buf, sizeof(uri)), 0);
403 	ret = lwm2m_get_string(&path, buf, sizeof(uri));
404 	zassert_equal(ret, 0);
405 	ret = lwm2m_get_string(&path, buf, strlen(uri));
406 	zassert_equal(ret, -ENOMEM);
407 	/* Corner case: we request exactly as much is stored in opaque resource, */
408 	/* but because we request as a string, it must have room for terminator. */
409 	ret = lwm2m_get_string(&path, buf, len);
410 	zassert_equal(ret, -ENOMEM);
411 }
412 
ZTEST(lwm2m_registry,test_lock_unlock)413 ZTEST(lwm2m_registry, test_lock_unlock)
414 {
415 	/* Should be recursive mutex and should not block */
416 	lwm2m_registry_lock();
417 	lwm2m_registry_lock();
418 	lwm2m_registry_unlock();
419 	lwm2m_registry_unlock();
420 }
421 
ZTEST(lwm2m_registry,test_resource_wrappers)422 ZTEST(lwm2m_registry, test_resource_wrappers)
423 {
424 	zassert_not_null(lwm2m_engine_obj_list());
425 	zassert_not_null(lwm2m_engine_obj_inst_list());
426 }
427 
ZTEST(lwm2m_registry,test_unregister_obj)428 ZTEST(lwm2m_registry, test_unregister_obj)
429 {
430 
431 	struct lwm2m_obj_path none = {0};
432 	struct lwm2m_engine_obj *obj;
433 
434 	zassert_is_null(lwm2m_engine_get_obj(&none));
435 
436 	obj = lwm2m_engine_get_obj(&LWM2M_OBJ(1));
437 
438 	zassert_not_null(obj);
439 	lwm2m_unregister_obj(obj);
440 	zassert_is_null(lwm2m_engine_get_obj(&LWM2M_OBJ(1)));
441 }
442 
ZTEST(lwm2m_registry,test_next_engine_obj_inst)443 ZTEST(lwm2m_registry, test_next_engine_obj_inst)
444 {
445 	zassert_equal(lwm2m_create_object_inst(&LWM2M_OBJ(3303, 0)), 0);
446 	zassert_equal(lwm2m_create_object_inst(&LWM2M_OBJ(3303, 1)), 0);
447 
448 	struct lwm2m_engine_obj_inst *oi = lwm2m_engine_get_obj_inst(&LWM2M_OBJ(3303, 1));
449 
450 	zassert_not_null(oi);
451 
452 	zassert_not_null(next_engine_obj_inst(3303, 0));
453 	zassert_equal(oi, next_engine_obj_inst(3303, 0));
454 	zassert_is_null(next_engine_obj_inst(3303, 1));
455 
456 	zassert_equal(lwm2m_delete_object_inst(&LWM2M_OBJ(3303, 0)), 0);
457 	zassert_equal(lwm2m_delete_object_inst(&LWM2M_OBJ(3303, 1)), 0);
458 	zassert_is_null(lwm2m_engine_get_obj_inst(&LWM2M_OBJ(3303, 1)));
459 }
460 
ZTEST(lwm2m_registry,test_null_strings)461 ZTEST(lwm2m_registry, test_null_strings)
462 {
463 	int ret;
464 	char buf[256] = {0};
465 	struct lwm2m_obj_path path = LWM2M_OBJ(0, 0, 0);
466 
467 	ret = lwm2m_register_post_write_callback(&path, post_write_cb);
468 	zassert_equal(ret, 0);
469 
470 	callback_checker = 0;
471 	ret = lwm2m_set_string(&path, "string");
472 	zassert_equal(ret, 0);
473 	zassert_equal(callback_checker, 0x02);
474 	ret = lwm2m_get_string(&path, buf, sizeof(buf));
475 	zassert_equal(ret, 0);
476 	zassert_equal(strlen(buf), strlen("string"));
477 
478 	callback_checker = 0;
479 	ret = lwm2m_set_string(&path, "");
480 	zassert_equal(ret, 0);
481 	zassert_equal(callback_checker, 0x02);
482 	ret = lwm2m_get_string(&path, buf, sizeof(buf));
483 	zassert_equal(ret, 0);
484 	zassert_equal(strlen(buf), 0);
485 
486 	callback_checker = 0;
487 	ret = lwm2m_set_opaque(&path, NULL, 0);
488 	zassert_equal(ret, 0);
489 	zassert_equal(callback_checker, 0x02);
490 	ret = lwm2m_get_string(&path, buf, sizeof(buf));
491 	zassert_equal(ret, 0);
492 	zassert_equal(strlen(buf), 0);
493 }
494 
ZTEST(lwm2m_registry,test_obj_version)495 ZTEST(lwm2m_registry, test_obj_version)
496 {
497 #if defined(CONFIG_LWM2M_ENGINE_ALWAYS_REPORT_OBJ_VERSION)
498 	zassert_true(lwm2m_engine_shall_report_obj_version(lwm2m_engine_get_obj(&LWM2M_OBJ(0))));
499 	zassert_true(
500 		lwm2m_engine_shall_report_obj_version(lwm2m_engine_get_obj(&LWM2M_OBJ(32768))));
501 	zassert_true(lwm2m_engine_shall_report_obj_version(lwm2m_engine_get_obj(&LWM2M_OBJ(3303))));
502 #else
503 	zassert_false(lwm2m_engine_shall_report_obj_version(lwm2m_engine_get_obj(&LWM2M_OBJ(0))));
504 	zassert_false(
505 		lwm2m_engine_shall_report_obj_version(lwm2m_engine_get_obj(&LWM2M_OBJ(32768))));
506 	zassert_true(lwm2m_engine_shall_report_obj_version(lwm2m_engine_get_obj(&LWM2M_OBJ(3303))));
507 #endif
508 }
509 
ZTEST(lwm2m_registry,test_resource_cache)510 ZTEST(lwm2m_registry, test_resource_cache)
511 {
512 	struct lwm2m_obj_path path = LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_BOOL);
513 	struct lwm2m_time_series_elem e;
514 
515 	/* Resource cache is turned off */
516 	zassert_is_null(lwm2m_cache_entry_get_by_object(&path));
517 	zassert_equal(lwm2m_enable_cache(&path, &e, 1), -ENOTSUP);
518 	zassert_false(lwm2m_cache_write(NULL, NULL));
519 	zassert_false(lwm2m_cache_read(NULL, NULL));
520 	zassert_equal(lwm2m_cache_size(NULL), 0);
521 }
522 
ZTEST(lwm2m_registry,test_set_bulk)523 ZTEST(lwm2m_registry, test_set_bulk)
524 {
525 	bool b = true;
526 	uint8_t opaque[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
527 	char string[] = "Hello world";
528 	uint8_t u8 = 80;
529 	int8_t s8 = -80;
530 	uint16_t u16 = 160;
531 	int16_t s16 = -160;
532 	uint32_t u32 = 320;
533 	int32_t s32 = -320;
534 	int64_t s64 = -640;
535 	time_t t = 1687949518;
536 	double d = 3.14151;
537 	double d2;
538 	struct lwm2m_objlnk objl = {.obj_id = 10, .obj_inst = 20};
539 
540 	struct lwm2m_res_item res_items[] = {
541 		{&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_BOOL), &b, sizeof(b)},
542 		{&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_OPAQUE), &opaque, sizeof(opaque)},
543 		{&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_STRING), &string, sizeof(string)},
544 		{&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_U8), &u8, sizeof(u8)},
545 		{&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_S8), &s8, sizeof(s8)},
546 		{&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_U16), &u16, sizeof(u16)},
547 		{&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_S16), &s16, sizeof(s16)},
548 		{&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_U32), &u32, sizeof(u32)},
549 		{&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_S32), &s32, sizeof(s32)},
550 		{&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_S64), &s64, sizeof(s64)},
551 		{&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_TIME), &t, sizeof(t)},
552 		{&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_FLOAT), &d, sizeof(d)},
553 		{&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_OBJLNK), &objl, sizeof(objl)}
554 	};
555 
556 	zassert_equal(lwm2m_set_bulk(res_items, ARRAY_SIZE(res_items)), 0);
557 
558 	zassert_equal(lwm2m_get_bool(&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_BOOL), &b), 0);
559 	zassert_equal(lwm2m_get_opaque(&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_OPAQUE), &opaque,
560 		sizeof(opaque)), 0);
561 	zassert_equal(lwm2m_get_string(&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_STRING), &string,
562 		sizeof(string)), 0);
563 	zassert_equal(lwm2m_get_u8(&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_U8), &u8), 0);
564 	zassert_equal(lwm2m_get_s8(&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_S8), &s8), 0);
565 	zassert_equal(lwm2m_get_u16(&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_U16), &u16), 0);
566 	zassert_equal(lwm2m_get_s16(&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_S16), &s16), 0);
567 	zassert_equal(lwm2m_get_u32(&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_U32), &u32), 0);
568 	zassert_equal(lwm2m_get_s32(&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_S32), &s32), 0);
569 	zassert_equal(lwm2m_get_s64(&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_S64), &s64), 0);
570 	zassert_equal(lwm2m_get_time(&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_TIME), &t), 0);
571 	zassert_equal(lwm2m_get_f64(&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_FLOAT), &d2), 0);
572 	zassert_equal(lwm2m_get_objlnk(&LWM2M_OBJ(TEST_OBJ_ID, 0, LWM2M_RES_TYPE_OBJLNK),
573 		&objl), 0);
574 
575 	zassert_equal(b, true);
576 	zassert_equal(memcmp(opaque, &(uint8_t[6]) {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
577 		sizeof(opaque)), 0);
578 	zassert_str_equal(string, "Hello world");
579 	zassert_equal(u8, 80);
580 	zassert_equal(s8, -80);
581 	zassert_equal(u16, 160);
582 	zassert_equal(s16, -160);
583 	zassert_equal(u32, 320);
584 	zassert_equal(s32, -320);
585 	zassert_equal(s64, -640);
586 	zassert_equal(t, 1687949518);
587 	zassert_equal(d, d2);
588 	zassert_equal(memcmp(&objl, &(struct lwm2m_objlnk){.obj_id = 10, .obj_inst = 20},
589 		sizeof(objl)), 0);
590 }
591