From 2c771414bdff0a655db2605806b2deff4f51c425 Mon Sep 17 00:00:00 2001 From: Steve Karg Date: Wed, 14 Jun 2023 17:13:52 -0500 Subject: [PATCH] fix BACnet Array size encoding (#437) * fix BACnet Array size encoding * test BACnet Array size encoding --------- Co-authored-by: Steve Karg --- src/bacnet/bacdcode.c | 2 +- test/bacnet/bacdcode/src/main.c | 65 ++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/bacnet/bacdcode.c b/src/bacnet/bacdcode.c index 1f10aeed..30fa087a 100644 --- a/src/bacnet/bacdcode.c +++ b/src/bacnet/bacdcode.c @@ -3116,7 +3116,7 @@ int bacnet_array_encode(uint32_t object_instance, if (len > max_apdu) { apdu_len = BACNET_STATUS_ABORT; } else { - len = encode_application_unsigned(NULL, array_size); + len = encode_application_unsigned(apdu, array_size); apdu_len = len; } } else if (array_index == BACNET_ARRAY_ALL) { diff --git a/test/bacnet/bacdcode/src/main.c b/test/bacnet/bacdcode/src/main.c index 2bfbcad1..0020b483 100644 --- a/test/bacnet/bacdcode/src/main.c +++ b/test/bacnet/bacdcode/src/main.c @@ -1295,6 +1295,68 @@ static void testDateContextDecodes(void) zassert_equal(in.wday, out.wday, NULL); zassert_equal(in.year, out.year, NULL); } + +/** + * @brief Encode a BACnetARRAY property element; a function template + * @param object_instance [in] BACnet network port object instance number + * @param array_index [in] array index requested: + * 0 to N for individual array members + * @param apdu [out] Buffer in which the APDU contents are built, or NULL to + * return the length of buffer if it had been built + * @return The length of the apdu encoded or + * BACNET_STATUS_ERROR for ERROR_CODE_INVALID_ARRAY_INDEX + */ +static int bacnet_array_property_element_encode( + uint32_t object_instance, BACNET_ARRAY_INDEX array_index, uint8_t *apdu) +{ + int apdu_len = BACNET_STATUS_ERROR; + + if (array_index < 1) { + apdu_len = encode_application_object_id(apdu, OBJECT_DEVICE, + object_instance); + } + + return apdu_len; +} + +static void test_bacnet_array_encode(void) +{ + uint32_t object_instance = 0; + BACNET_ARRAY_INDEX array_index = 0; + BACNET_UNSIGNED_INTEGER array_size = 1; + uint8_t apdu[480] = { 0 }; + int apdu_len, len; + uint8_t tag_number = 0; + uint32_t len_value = 0; + BACNET_UNSIGNED_INTEGER decoded_value = 0; + + /* element zero returns the array size */ + apdu_len = bacnet_array_encode(object_instance, array_index, + bacnet_array_property_element_encode, + array_size, apdu, sizeof(apdu)); + zassert_true(apdu_len > 0, NULL); + len = decode_tag_number_and_value(apdu, &tag_number, &len_value); + zassert_true(len > 0, NULL); + zassert_equal(tag_number, BACNET_APPLICATION_TAG_UNSIGNED_INT, NULL); + len = decode_unsigned(&apdu[len], len_value, &decoded_value); + zassert_equal(decoded_value, array_size, NULL); + /* element 1 returns the first element */ + array_index = 1; + apdu_len = bacnet_array_encode(object_instance, array_index, + bacnet_array_property_element_encode, + array_size, apdu, sizeof(apdu)); + zassert_true(apdu_len > 0, NULL); + len = decode_tag_number_and_value(apdu, &tag_number, &len_value); + zassert_true(len > 0, NULL); + zassert_equal(tag_number, BACNET_APPLICATION_TAG_OBJECT_ID, NULL); + /* element 2, in this test case, returns an error */ + array_index = 2; + apdu_len = bacnet_array_encode(object_instance, array_index, + bacnet_array_property_element_encode, + array_size, apdu, sizeof(apdu)); + zassert_true(apdu_len < 0, NULL); +} + /** * @} */ @@ -1326,7 +1388,8 @@ void test_main(void) ztest_unit_test(testTimeContextDecodes), ztest_unit_test(testDateContextDecodes), ztest_unit_test(testOctetStringContextDecodes), - ztest_unit_test(testBACDCodeDouble) + ztest_unit_test(testBACDCodeDouble), + ztest_unit_test(test_bacnet_array_encode) ); ztest_run_test_suite(bacdcode_tests);