1 /*
2 * Copyright (c) 2022 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/ztest.h>
9
10 #include "lwm2m_engine.h"
11 #include "lwm2m_rw_link_format.h"
12
13 #define TEST_SSID 101
14 #define TEST_PMIN 5
15 #define TEST_PMAX 200
16
17 #define TEST_OBJ_ID 0xFFFF
18 #define TEST_OBJ_INST_ID 0
19
20 #define TEST_RES_S8 0
21
22 #define TEST_OBJ_RES_MAX_ID 2
23
24 static struct lwm2m_engine_obj test_obj;
25
26 static struct lwm2m_engine_obj_field test_fields[] = {
27 OBJ_FIELD_DATA(TEST_RES_S8, RW, S8),
28 };
29
30 static struct lwm2m_engine_obj_inst test_inst;
31 static struct lwm2m_engine_res test_res[TEST_OBJ_RES_MAX_ID];
32 static struct lwm2m_engine_res_inst test_res_inst[TEST_OBJ_RES_MAX_ID];
33
34 static int8_t test_s8;
35
test_obj_create(uint16_t obj_inst_id)36 static struct lwm2m_engine_obj_inst *test_obj_create(uint16_t obj_inst_id)
37 {
38 int i = 0, j = 0;
39
40 init_res_instance(test_res_inst, ARRAY_SIZE(test_res_inst));
41
42 INIT_OBJ_RES_DATA(TEST_RES_S8, test_res, i, test_res_inst, j,
43 &test_s8, sizeof(test_s8));
44
45 test_inst.resources = test_res;
46 test_inst.resource_count = i;
47
48 return &test_inst;
49 }
50
test_obj_init(void)51 static void test_obj_init(void)
52 {
53 struct lwm2m_engine_obj_inst *obj_inst = NULL;
54
55 test_obj.obj_id = TEST_OBJ_ID;
56 test_obj.version_major = 1;
57 test_obj.version_minor = 1;
58 test_obj.is_core = false;
59 test_obj.fields = test_fields;
60 test_obj.field_count = ARRAY_SIZE(test_fields);
61 test_obj.max_instance_count = 1U;
62 test_obj.create_cb = test_obj_create;
63
64 (void)lwm2m_register_obj(&test_obj);
65 (void)lwm2m_create_obj_inst(TEST_OBJ_ID, TEST_OBJ_INST_ID, &obj_inst);
66 }
67
test_attr_init(void)68 static void test_attr_init(void)
69 {
70 struct lwm2m_attr *attr;
71
72 attr = lwm2m_engine_get_next_attr(NULL, NULL);
73 attr->type = LWM2M_ATTR_PMIN;
74 attr->int_val = TEST_PMIN;
75 attr->ref = &test_inst;
76
77 attr = lwm2m_engine_get_next_attr(NULL, NULL);
78 attr->type = LWM2M_ATTR_PMAX;
79 attr->int_val = TEST_PMAX;
80 attr->ref = &test_res;
81 }
82
83 static struct lwm2m_output_context test_out;
84 static struct lwm2m_obj_path test_path;
85 static struct coap_packet test_packet;
86 static uint8_t test_payload[128];
87 static struct link_format_out_formatter_data test_formatter_data;
88
context_reset(void)89 static void context_reset(void)
90 {
91 memset(&test_out, 0, sizeof(test_out));
92 test_out.writer = &link_format_writer;
93 test_out.out_cpkt = &test_packet;
94 test_out.user_data = &test_formatter_data;
95
96 memset(&test_payload, 0, sizeof(test_payload));
97 memset(&test_packet, 0, sizeof(test_packet));
98 test_packet.data = test_payload;
99 test_packet.max_len = sizeof(test_payload);
100
101 memset(&test_path, 0, sizeof(test_path));
102 test_path.level = LWM2M_PATH_LEVEL_OBJECT;
103 test_path.obj_id = TEST_OBJ_ID;
104 test_path.obj_inst_id = TEST_OBJ_INST_ID;
105 test_path.res_id = TEST_RES_S8;
106
107 memset(&test_formatter_data, 0, sizeof(test_formatter_data));
108 test_formatter_data.is_first = true;
109 test_formatter_data.request_level = LWM2M_PATH_LEVEL_OBJECT;
110 }
111
test_prepare(void * dummy)112 static void test_prepare(void *dummy)
113 {
114 context_reset();
115 }
116
test_prepare_nomem(void * dummy)117 static void test_prepare_nomem(void *dummy)
118 {
119 context_reset();
120
121 test_packet.offset = sizeof(test_payload);
122 }
123
ZTEST(net_content_link_format,test_put_begin_discovery)124 ZTEST(net_content_link_format, test_put_begin_discovery)
125 {
126 int ret;
127 const char *expected_payload = "";
128
129 test_formatter_data.mode = LINK_FORMAT_MODE_DISCOVERY;
130
131 ret = link_format_writer.put_begin(&test_out, &test_path);
132 zassert_equal(ret, strlen(expected_payload),
133 "Invalid length returned");
134 zassert_mem_equal(test_out.out_cpkt->data, expected_payload,
135 strlen(expected_payload), "Invalid payload format");
136 zassert_equal(test_out.out_cpkt->offset, strlen(expected_payload),
137 "Invalid packet offset");
138 }
139
ZTEST(net_content_link_format,test_put_begin_bs_discovery)140 ZTEST(net_content_link_format, test_put_begin_bs_discovery)
141 {
142 int ret;
143 const char *expected_payload = "</>;lwm2m=\"1.0\"";
144
145 test_formatter_data.mode = LINK_FORMAT_MODE_BOOTSTRAP_DISCOVERY;
146
147 ret = link_format_writer.put_begin(&test_out, &test_path);
148 zassert_equal(ret, strlen(expected_payload),
149 "Invalid length returned");
150 zassert_mem_equal(test_out.out_cpkt->data, expected_payload,
151 strlen(expected_payload), "Invalid payload format");
152 zassert_equal(test_out.out_cpkt->offset, strlen(expected_payload),
153 "Invalid packet offset");
154 }
155
ZTEST(net_content_link_format,test_put_begin_register)156 ZTEST(net_content_link_format, test_put_begin_register)
157 {
158 int ret;
159 const char *expected_payload = "</>;ct=11543";
160
161 test_formatter_data.mode = LINK_FORMAT_MODE_REGISTER;
162
163 ret = link_format_writer.put_begin(&test_out, &test_path);
164 zassert_equal(ret, strlen(expected_payload),
165 "Invalid length returned");
166 zassert_mem_equal(test_out.out_cpkt->data, expected_payload,
167 strlen(expected_payload), "Invalid payload format");
168 zassert_equal(test_out.out_cpkt->offset, strlen(expected_payload),
169 "Invalid packet offset");
170 }
171
ZTEST(net_content_link_format_nomem,test_put_begin_nomem)172 ZTEST(net_content_link_format_nomem, test_put_begin_nomem)
173 {
174 int ret;
175
176 test_formatter_data.mode = LINK_FORMAT_MODE_REGISTER;
177
178 ret = link_format_writer.put_begin(&test_out, &test_path);
179 zassert_equal(ret, -ENOMEM, "Invalid error code returned");
180 }
181
182 struct test_case_corelink {
183 uint8_t request_level;
184 uint8_t path_level;
185 const char *expected_payload;
186 };
187
ZTEST(net_content_link_format,test_put_corelink_discovery)188 ZTEST(net_content_link_format, test_put_corelink_discovery)
189 {
190 int ret;
191 int i;
192 struct test_case_corelink test_case[] = {
193 {
194 .request_level = LWM2M_PATH_LEVEL_OBJECT,
195 .path_level = LWM2M_PATH_LEVEL_OBJECT,
196 .expected_payload = "</65535>;ver=1.1"
197 },
198 {
199 .request_level = LWM2M_PATH_LEVEL_OBJECT,
200 .path_level = LWM2M_PATH_LEVEL_OBJECT_INST,
201 .expected_payload = "</65535/0>"
202 },
203 {
204 .request_level = LWM2M_PATH_LEVEL_OBJECT,
205 .path_level = LWM2M_PATH_LEVEL_RESOURCE,
206 .expected_payload = "</65535/0/0>"
207 },
208 {
209 .request_level = LWM2M_PATH_LEVEL_OBJECT_INST,
210 .path_level = LWM2M_PATH_LEVEL_OBJECT_INST,
211 .expected_payload = "</65535/0>;pmin=" STRINGIFY(TEST_PMIN)
212 },
213 {
214 .request_level = LWM2M_PATH_LEVEL_OBJECT_INST,
215 .path_level = LWM2M_PATH_LEVEL_RESOURCE,
216 .expected_payload = "</65535/0/0>;pmax=" STRINGIFY(TEST_PMAX)
217 },
218 {
219 .request_level = LWM2M_PATH_LEVEL_RESOURCE,
220 .path_level = LWM2M_PATH_LEVEL_RESOURCE,
221 .expected_payload = "</65535/0/0>;pmin=" STRINGIFY(TEST_PMIN)
222 ";pmax=" STRINGIFY(TEST_PMAX)
223 },
224 };
225
226 for (i = 0; i < ARRAY_SIZE(test_case); i++) {
227 context_reset();
228
229 test_formatter_data.mode = LINK_FORMAT_MODE_DISCOVERY;
230 test_formatter_data.request_level = test_case[i].request_level;
231 test_path.level = test_case[i].path_level;
232
233 ret = link_format_writer.put_corelink(&test_out, &test_path);
234 zassert_equal(ret, strlen(test_case[i].expected_payload),
235 "Invalid length returned");
236 zassert_mem_equal(test_out.out_cpkt->data,
237 test_case[i].expected_payload,
238 strlen(test_case[i].expected_payload),
239 "Invalid payload format");
240 zassert_equal(test_out.out_cpkt->offset,
241 strlen(test_case[i].expected_payload),
242 "Invalid packet offset");
243 }
244 }
245
ZTEST(net_content_link_format,test_put_corelink_bs_discovery)246 ZTEST(net_content_link_format, test_put_corelink_bs_discovery)
247 {
248 int ret;
249 int i;
250 struct test_case_corelink test_case[] = {
251 {
252 .request_level = LWM2M_PATH_LEVEL_NONE,
253 .path_level = LWM2M_PATH_LEVEL_OBJECT,
254 .expected_payload = "</65535>;ver=1.1"
255 },
256 {
257 .request_level = LWM2M_PATH_LEVEL_NONE,
258 .path_level = LWM2M_PATH_LEVEL_OBJECT_INST,
259 .expected_payload = "</65535/0>"
260 },
261 {
262 .request_level = LWM2M_PATH_LEVEL_OBJECT,
263 .path_level = LWM2M_PATH_LEVEL_OBJECT,
264 .expected_payload = "</65535>;ver=1.1"
265 },
266 {
267 .request_level = LWM2M_PATH_LEVEL_OBJECT,
268 .path_level = LWM2M_PATH_LEVEL_OBJECT_INST,
269 .expected_payload = "</65535/0>"
270 },
271 };
272
273 for (i = 0; i < ARRAY_SIZE(test_case); i++) {
274 context_reset();
275
276 test_formatter_data.mode = LINK_FORMAT_MODE_BOOTSTRAP_DISCOVERY;
277 test_formatter_data.request_level = test_case[i].request_level;
278 test_path.level = test_case[i].path_level;
279
280 ret = link_format_writer.put_corelink(&test_out, &test_path);
281 zassert_equal(ret, strlen(test_case[i].expected_payload),
282 "Invalid length returned");
283 zassert_mem_equal(test_out.out_cpkt->data,
284 test_case[i].expected_payload,
285 strlen(test_case[i].expected_payload),
286 "Invalid payload format");
287 zassert_equal(test_out.out_cpkt->offset,
288 strlen(test_case[i].expected_payload),
289 "Invalid packet offset");
290 }
291 }
292
ZTEST(net_content_link_format,test_put_corelink_bs_discovery_ssid)293 ZTEST(net_content_link_format, test_put_corelink_bs_discovery_ssid)
294 {
295 int ret;
296 int i;
297 char * const expected_payload[] = {
298 "</0/0>;ssid=" STRINGIFY(TEST_SSID),
299 "</1/0>;ssid=" STRINGIFY(TEST_SSID),
300 };
301 uint16_t test_obj_id[] = {
302 LWM2M_OBJECT_SECURITY_ID,
303 LWM2M_OBJECT_SERVER_ID,
304 };
305
306 for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
307 context_reset();
308
309 test_formatter_data.mode = LINK_FORMAT_MODE_BOOTSTRAP_DISCOVERY;
310 test_formatter_data.request_level = LWM2M_PATH_LEVEL_NONE;
311 test_path.level = LWM2M_PATH_LEVEL_OBJECT_INST;
312 test_path.obj_id = test_obj_id[i];
313 test_path.obj_inst_id = 0;
314
315 ret = link_format_writer.put_corelink(&test_out, &test_path);
316 zassert_equal(ret, strlen(expected_payload[i]),
317 "Invalid length returned");
318 zassert_mem_equal(test_out.out_cpkt->data,
319 expected_payload[i],
320 strlen(expected_payload[i]),
321 "Invalid payload format");
322 zassert_equal(test_out.out_cpkt->offset,
323 strlen(expected_payload[i]),
324 "Invalid packet offset");
325 }
326 }
327
ZTEST(net_content_link_format,test_put_corelink_register)328 ZTEST(net_content_link_format, test_put_corelink_register)
329 {
330 int ret;
331 int i;
332 struct test_case_corelink test_case[] = {
333 {
334 .request_level = LWM2M_PATH_LEVEL_NONE,
335 .path_level = LWM2M_PATH_LEVEL_OBJECT,
336 .expected_payload = "</65535>;ver=1.1"
337 },
338 {
339 .request_level = LWM2M_PATH_LEVEL_NONE,
340 .path_level = LWM2M_PATH_LEVEL_OBJECT_INST,
341 .expected_payload = "</65535/0>"
342 },
343 };
344
345 for (i = 0; i < ARRAY_SIZE(test_case); i++) {
346 context_reset();
347
348 test_formatter_data.mode = LINK_FORMAT_MODE_REGISTER;
349 test_formatter_data.request_level = test_case[i].request_level;
350 test_path.level = test_case[i].path_level;
351
352 ret = link_format_writer.put_corelink(&test_out, &test_path);
353 zassert_equal(ret, strlen(test_case[i].expected_payload),
354 "Invalid length returned");
355 zassert_mem_equal(test_out.out_cpkt->data,
356 test_case[i].expected_payload,
357 strlen(test_case[i].expected_payload),
358 "Invalid payload format");
359 zassert_equal(test_out.out_cpkt->offset,
360 strlen(test_case[i].expected_payload),
361 "Invalid packet offset");
362 }
363 }
364
ZTEST(net_content_link_format_nomem,test_put_corelink_nomem)365 ZTEST(net_content_link_format_nomem, test_put_corelink_nomem)
366 {
367 int ret;
368
369 test_formatter_data.mode = LINK_FORMAT_MODE_REGISTER;
370 test_formatter_data.request_level = LWM2M_PATH_LEVEL_NONE;
371
372 ret = link_format_writer.put_corelink(&test_out, &test_path);
373 zassert_equal(ret, -ENOMEM, "Invalid error code returned");
374 }
375
obj_attr_init(void)376 static void *obj_attr_init(void)
377 {
378 test_obj_init();
379 test_attr_init();
380 lwm2m_set_u16(&LWM2M_OBJ(0, 0, 10), TEST_SSID);
381 lwm2m_set_u16(&LWM2M_OBJ(1, 0, 0), TEST_SSID);
382 return NULL;
383 }
384
385 ZTEST_SUITE(net_content_link_format, NULL, obj_attr_init, test_prepare, NULL, NULL);
386 ZTEST_SUITE(net_content_link_format_nomem, NULL, obj_attr_init, test_prepare_nomem, NULL, NULL);
387