/* * Copyright (c) 2022 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include "lwm2m_engine.h" #include "lwm2m_rw_link_format.h" #define TEST_SSID 101 #define TEST_PMIN 5 #define TEST_PMAX 200 #define TEST_OBJ_ID 0xFFFF #define TEST_OBJ_INST_ID 0 #define TEST_RES_S8 0 #define TEST_OBJ_RES_MAX_ID 2 static struct lwm2m_engine_obj test_obj; static struct lwm2m_engine_obj_field test_fields[] = { OBJ_FIELD_DATA(TEST_RES_S8, RW, S8), }; static struct lwm2m_engine_obj_inst test_inst; static struct lwm2m_engine_res test_res[TEST_OBJ_RES_MAX_ID]; static struct lwm2m_engine_res_inst test_res_inst[TEST_OBJ_RES_MAX_ID]; static int8_t test_s8; static struct lwm2m_engine_obj_inst *test_obj_create(uint16_t obj_inst_id) { int i = 0, j = 0; init_res_instance(test_res_inst, ARRAY_SIZE(test_res_inst)); INIT_OBJ_RES_DATA(TEST_RES_S8, test_res, i, test_res_inst, j, &test_s8, sizeof(test_s8)); test_inst.resources = test_res; test_inst.resource_count = i; return &test_inst; } static void test_obj_init(void) { struct lwm2m_engine_obj_inst *obj_inst = NULL; test_obj.obj_id = TEST_OBJ_ID; test_obj.version_major = 1; test_obj.version_minor = 1; test_obj.is_core = false; test_obj.fields = test_fields; test_obj.field_count = ARRAY_SIZE(test_fields); test_obj.max_instance_count = 1U; test_obj.create_cb = test_obj_create; (void)lwm2m_register_obj(&test_obj); (void)lwm2m_create_obj_inst(TEST_OBJ_ID, TEST_OBJ_INST_ID, &obj_inst); } static void test_attr_init(void) { struct lwm2m_attr *attr; attr = lwm2m_engine_get_next_attr(NULL, NULL); attr->type = LWM2M_ATTR_PMIN; attr->int_val = TEST_PMIN; attr->ref = &test_inst; attr = lwm2m_engine_get_next_attr(NULL, NULL); attr->type = LWM2M_ATTR_PMAX; attr->int_val = TEST_PMAX; attr->ref = &test_res; } static struct lwm2m_output_context test_out; static struct lwm2m_obj_path test_path; static struct coap_packet test_packet; static uint8_t test_payload[128]; static struct link_format_out_formatter_data test_formatter_data; static void context_reset(void) { memset(&test_out, 0, sizeof(test_out)); test_out.writer = &link_format_writer; test_out.out_cpkt = &test_packet; test_out.user_data = &test_formatter_data; memset(&test_payload, 0, sizeof(test_payload)); memset(&test_packet, 0, sizeof(test_packet)); test_packet.data = test_payload; test_packet.max_len = sizeof(test_payload); memset(&test_path, 0, sizeof(test_path)); test_path.level = LWM2M_PATH_LEVEL_OBJECT; test_path.obj_id = TEST_OBJ_ID; test_path.obj_inst_id = TEST_OBJ_INST_ID; test_path.res_id = TEST_RES_S8; memset(&test_formatter_data, 0, sizeof(test_formatter_data)); test_formatter_data.is_first = true; test_formatter_data.request_level = LWM2M_PATH_LEVEL_OBJECT; } static void test_prepare(void *dummy) { context_reset(); } static void test_prepare_nomem(void *dummy) { context_reset(); test_packet.offset = sizeof(test_payload); } ZTEST(net_content_link_format, test_put_begin_discovery) { int ret; const char *expected_payload = ""; test_formatter_data.mode = LINK_FORMAT_MODE_DISCOVERY; ret = link_format_writer.put_begin(&test_out, &test_path); zassert_equal(ret, strlen(expected_payload), "Invalid length returned"); zassert_mem_equal(test_out.out_cpkt->data, expected_payload, strlen(expected_payload), "Invalid payload format"); zassert_equal(test_out.out_cpkt->offset, strlen(expected_payload), "Invalid packet offset"); } ZTEST(net_content_link_format, test_put_begin_bs_discovery) { int ret; const char *expected_payload = ";lwm2m=\"1.0\""; test_formatter_data.mode = LINK_FORMAT_MODE_BOOTSTRAP_DISCOVERY; ret = link_format_writer.put_begin(&test_out, &test_path); zassert_equal(ret, strlen(expected_payload), "Invalid length returned"); zassert_mem_equal(test_out.out_cpkt->data, expected_payload, strlen(expected_payload), "Invalid payload format"); zassert_equal(test_out.out_cpkt->offset, strlen(expected_payload), "Invalid packet offset"); } ZTEST(net_content_link_format, test_put_begin_register) { int ret; const char *expected_payload = ";ct=11543"; test_formatter_data.mode = LINK_FORMAT_MODE_REGISTER; ret = link_format_writer.put_begin(&test_out, &test_path); zassert_equal(ret, strlen(expected_payload), "Invalid length returned"); zassert_mem_equal(test_out.out_cpkt->data, expected_payload, strlen(expected_payload), "Invalid payload format"); zassert_equal(test_out.out_cpkt->offset, strlen(expected_payload), "Invalid packet offset"); } ZTEST(net_content_link_format_nomem, test_put_begin_nomem) { int ret; test_formatter_data.mode = LINK_FORMAT_MODE_REGISTER; ret = link_format_writer.put_begin(&test_out, &test_path); zassert_equal(ret, -ENOMEM, "Invalid error code returned"); } struct test_case_corelink { uint8_t request_level; uint8_t path_level; const char *expected_payload; }; ZTEST(net_content_link_format, test_put_corelink_discovery) { int ret; int i; struct test_case_corelink test_case[] = { { .request_level = LWM2M_PATH_LEVEL_OBJECT, .path_level = LWM2M_PATH_LEVEL_OBJECT, .expected_payload = ";ver=1.1" }, { .request_level = LWM2M_PATH_LEVEL_OBJECT, .path_level = LWM2M_PATH_LEVEL_OBJECT_INST, .expected_payload = "" }, { .request_level = LWM2M_PATH_LEVEL_OBJECT, .path_level = LWM2M_PATH_LEVEL_RESOURCE, .expected_payload = "" }, { .request_level = LWM2M_PATH_LEVEL_OBJECT_INST, .path_level = LWM2M_PATH_LEVEL_OBJECT_INST, .expected_payload = ";pmin=" STRINGIFY(TEST_PMIN) }, { .request_level = LWM2M_PATH_LEVEL_OBJECT_INST, .path_level = LWM2M_PATH_LEVEL_RESOURCE, .expected_payload = ";pmax=" STRINGIFY(TEST_PMAX) }, { .request_level = LWM2M_PATH_LEVEL_RESOURCE, .path_level = LWM2M_PATH_LEVEL_RESOURCE, .expected_payload = ";pmin=" STRINGIFY(TEST_PMIN) ";pmax=" STRINGIFY(TEST_PMAX) }, }; for (i = 0; i < ARRAY_SIZE(test_case); i++) { context_reset(); test_formatter_data.mode = LINK_FORMAT_MODE_DISCOVERY; test_formatter_data.request_level = test_case[i].request_level; test_path.level = test_case[i].path_level; ret = link_format_writer.put_corelink(&test_out, &test_path); zassert_equal(ret, strlen(test_case[i].expected_payload), "Invalid length returned"); zassert_mem_equal(test_out.out_cpkt->data, test_case[i].expected_payload, strlen(test_case[i].expected_payload), "Invalid payload format"); zassert_equal(test_out.out_cpkt->offset, strlen(test_case[i].expected_payload), "Invalid packet offset"); } } ZTEST(net_content_link_format, test_put_corelink_bs_discovery) { int ret; int i; struct test_case_corelink test_case[] = { { .request_level = LWM2M_PATH_LEVEL_NONE, .path_level = LWM2M_PATH_LEVEL_OBJECT, .expected_payload = ";ver=1.1" }, { .request_level = LWM2M_PATH_LEVEL_NONE, .path_level = LWM2M_PATH_LEVEL_OBJECT_INST, .expected_payload = "" }, { .request_level = LWM2M_PATH_LEVEL_OBJECT, .path_level = LWM2M_PATH_LEVEL_OBJECT, .expected_payload = ";ver=1.1" }, { .request_level = LWM2M_PATH_LEVEL_OBJECT, .path_level = LWM2M_PATH_LEVEL_OBJECT_INST, .expected_payload = "" }, }; for (i = 0; i < ARRAY_SIZE(test_case); i++) { context_reset(); test_formatter_data.mode = LINK_FORMAT_MODE_BOOTSTRAP_DISCOVERY; test_formatter_data.request_level = test_case[i].request_level; test_path.level = test_case[i].path_level; ret = link_format_writer.put_corelink(&test_out, &test_path); zassert_equal(ret, strlen(test_case[i].expected_payload), "Invalid length returned"); zassert_mem_equal(test_out.out_cpkt->data, test_case[i].expected_payload, strlen(test_case[i].expected_payload), "Invalid payload format"); zassert_equal(test_out.out_cpkt->offset, strlen(test_case[i].expected_payload), "Invalid packet offset"); } } ZTEST(net_content_link_format, test_put_corelink_bs_discovery_ssid) { int ret; int i; char * const expected_payload[] = { ";ssid=" STRINGIFY(TEST_SSID), ";ssid=" STRINGIFY(TEST_SSID), }; uint16_t test_obj_id[] = { LWM2M_OBJECT_SECURITY_ID, LWM2M_OBJECT_SERVER_ID, }; for (i = 0; i < ARRAY_SIZE(expected_payload); i++) { context_reset(); test_formatter_data.mode = LINK_FORMAT_MODE_BOOTSTRAP_DISCOVERY; test_formatter_data.request_level = LWM2M_PATH_LEVEL_NONE; test_path.level = LWM2M_PATH_LEVEL_OBJECT_INST; test_path.obj_id = test_obj_id[i]; test_path.obj_inst_id = 0; ret = link_format_writer.put_corelink(&test_out, &test_path); zassert_equal(ret, strlen(expected_payload[i]), "Invalid length returned"); zassert_mem_equal(test_out.out_cpkt->data, expected_payload[i], strlen(expected_payload[i]), "Invalid payload format"); zassert_equal(test_out.out_cpkt->offset, strlen(expected_payload[i]), "Invalid packet offset"); } } ZTEST(net_content_link_format, test_put_corelink_register) { int ret; int i; struct test_case_corelink test_case[] = { { .request_level = LWM2M_PATH_LEVEL_NONE, .path_level = LWM2M_PATH_LEVEL_OBJECT, .expected_payload = ";ver=1.1" }, { .request_level = LWM2M_PATH_LEVEL_NONE, .path_level = LWM2M_PATH_LEVEL_OBJECT_INST, .expected_payload = "" }, }; for (i = 0; i < ARRAY_SIZE(test_case); i++) { context_reset(); test_formatter_data.mode = LINK_FORMAT_MODE_REGISTER; test_formatter_data.request_level = test_case[i].request_level; test_path.level = test_case[i].path_level; ret = link_format_writer.put_corelink(&test_out, &test_path); zassert_equal(ret, strlen(test_case[i].expected_payload), "Invalid length returned"); zassert_mem_equal(test_out.out_cpkt->data, test_case[i].expected_payload, strlen(test_case[i].expected_payload), "Invalid payload format"); zassert_equal(test_out.out_cpkt->offset, strlen(test_case[i].expected_payload), "Invalid packet offset"); } } ZTEST(net_content_link_format_nomem, test_put_corelink_nomem) { int ret; test_formatter_data.mode = LINK_FORMAT_MODE_REGISTER; test_formatter_data.request_level = LWM2M_PATH_LEVEL_NONE; ret = link_format_writer.put_corelink(&test_out, &test_path); zassert_equal(ret, -ENOMEM, "Invalid error code returned"); } static void *obj_attr_init(void) { test_obj_init(); test_attr_init(); lwm2m_set_u16(&LWM2M_OBJ(0, 0, 10), TEST_SSID); lwm2m_set_u16(&LWM2M_OBJ(1, 0, 0), TEST_SSID); return NULL; } ZTEST_SUITE(net_content_link_format, NULL, obj_attr_init, test_prepare, NULL, NULL); ZTEST_SUITE(net_content_link_format_nomem, NULL, obj_attr_init, test_prepare_nomem, NULL, NULL);