/* * Copyright (c) 2020 Legrand North America, LLC. * * SPDX-License-Identifier: MIT */ /* @file * @brief test BACnet integer encode/decode APIs */ #include #include /** * @addtogroup bacnet_tests * @{ */ /** * @brief Test encode/decode API for unsigned 16b integers */ static void testBACnetUnsigned16(void) { uint8_t apdu[32] = { 0 }; uint16_t value = 0, test_value = 0; int len = 0; /* Test invalid parameter values */ len = decode_unsigned16(&apdu[0], NULL); zassert_equal(len, 2, NULL); /* TODO: How do we indicate an error? */ /* Test value zero (0) */ memset(apdu, -1, sizeof(apdu)); len = encode_unsigned16(&apdu[0], value); zassert_equal(len, 2, NULL); test_value = (uint16_t) ~0U; len = decode_unsigned16(&apdu[0], &test_value); zassert_equal(len, 2, NULL); zassert_equal(value, test_value, NULL); for (value = 1; value != 0; value = (value << 1) & ((1UL<<16)-1)) { len = encode_unsigned16(&apdu[0], value); zassert_equal(len, 2, NULL); test_value = (uint16_t) ~0U; len = decode_unsigned16(&apdu[0], &test_value); zassert_equal(value, test_value, NULL); } } /** * @brief Test encode/decode API for unsigned 24b integers */ static void testBACnetUnsigned24(void) { uint8_t apdu[32] = { 0 }; uint32_t value = 0, test_value = 0; int len = 0; /* Test invalid parameter values */ len = decode_unsigned24(&apdu[0], NULL); zassert_equal(len, 3, NULL); /* TODO: How do we indicate an error? */ /* Test value zero (0) */ memset(apdu, -1, sizeof(apdu)); len = encode_unsigned24(&apdu[0], value); zassert_equal(len, 3, NULL); test_value = ~0U; len = decode_unsigned24(&apdu[0], &test_value); zassert_equal(len, 3, NULL); zassert_equal(value, test_value, NULL); for (value = 1; value != 0; value = (value << 1) & ((1UL<<24)-1)) { len = encode_unsigned24(&apdu[0], value); zassert_equal(len, 3, NULL); test_value = ~0U; len = decode_unsigned24(&apdu[0], &test_value); zassert_equal(value, test_value, NULL); } } /** * @brief Test encode/decode API for unsigned 32b integers */ static void testBACnetUnsigned32(void) { uint8_t apdu[32] = { 0 }; uint32_t value = 0, test_value = 0; int len = 0; /* Test invalid parameter values */ len = decode_unsigned32(&apdu[0], NULL); zassert_equal(len, 4, NULL); /* TODO: How do we indicate an error? */ /* Test value zero (0) */ memset(apdu, -1, sizeof(apdu)); len = encode_unsigned32(&apdu[0], value); zassert_equal(len, 4, NULL); test_value = ~0U; len = decode_unsigned32(&apdu[0], &test_value); zassert_equal(len, 4, NULL); zassert_equal(value, test_value, NULL); for (value = 0x01; value != 0; value <<= 1) { len = encode_unsigned32(&apdu[0], value); zassert_equal(len, 4, NULL); test_value = ~0U; len = decode_unsigned32(&apdu[0], &test_value); zassert_equal(value, test_value, NULL); } } /** * @brief Test encode/decode API for unsigned 40b integers (if 64b supported) */ static void testBACnetUnsigned40(void) { #ifdef UINT64_MAX uint8_t apdu[64] = { 0 }; uint64_t value = 0, test_value = 0; int len = 0; /* Test invalid parameter values */ len = decode_unsigned40(&apdu[0], NULL); zassert_equal(len, 5, NULL); /* TODO: How do we indicate an error? */ /* Test value zero (0) */ memset(apdu, -1, sizeof(apdu)); len = encode_unsigned40(&apdu[0], value); zassert_equal(len, 5, NULL); test_value = ~0ULL; len = decode_unsigned40(&apdu[0], &test_value); zassert_equal(len, 5, NULL); zassert_equal(value, test_value, NULL); for (value = 1; value != 0; value = (value << 1) & ((1ULL<<40)-1)) { len = encode_unsigned40(&apdu[0], value); zassert_equal(len, 5, NULL); test_value = ~0ULL; len = decode_unsigned40(&apdu[0], &test_value); zassert_equal(len, 5, NULL); zassert_equal(value, test_value, NULL); } #else #warning "UINT64_MAX not supported!" ztest_test_skip(); #endif } /** * @brief Test encode/decode API for unsigned 48b integers (if 64b supported) */ static void testBACnetUnsigned48(void) { #ifdef UINT64_MAX uint8_t apdu[64] = { 0 }; uint64_t value = 0, test_value = 0; int len = 0; /* Test invalid parameter values */ len = decode_unsigned48(&apdu[0], NULL); zassert_equal(len, 6, NULL); /* TODO: How do we indicate an error? */ /* Test value zero (0) */ memset(apdu, -1, sizeof(apdu)); len = encode_unsigned48(&apdu[0], value); zassert_equal(len, 6, NULL); test_value = ~0ULL; len = decode_unsigned48(&apdu[0], &test_value); zassert_equal(len, 6, NULL); zassert_equal(value, test_value, NULL); for (value = 1; value != 0; value = (value << 1) & ((1ULL<<48)-1)) { len = encode_unsigned48(&apdu[0], value); zassert_equal(len, 6, NULL); test_value = ~0ULL; len = decode_unsigned48(&apdu[0], &test_value); zassert_equal(len, 6, NULL); zassert_equal(value, test_value, NULL); } #else #warning "UINT64_MAX not supported!" ztest_test_skip(); #endif } /** * @brief Test encode/decode API for unsigned 56b integers (if 64b supported) */ static void testBACnetUnsigned56(void) { #ifdef UINT64_MAX uint8_t apdu[64] = { 0 }; uint64_t value = 0, test_value = 0; int len = 0; /* Test invalid parameter values */ len = decode_unsigned56(&apdu[0], NULL); zassert_equal(len, 7, NULL); /* TODO: How do we indicate an error? */ /* Test value zero (0) */ memset(apdu, -1, sizeof(apdu)); len = encode_unsigned56(&apdu[0], value); zassert_equal(len, 7, NULL); test_value = ~0ULL; len = decode_unsigned56(&apdu[0], &test_value); zassert_equal(len, 7, NULL); zassert_equal(value, test_value, NULL); for (value = 1; value != 0; value = (value << 1) & ((1ULL<<56)-1)) { len = encode_unsigned56(&apdu[0], value); zassert_equal(len, 7, NULL); test_value = ~0ULL; len = decode_unsigned56(&apdu[0], &test_value); zassert_equal(len, 7, NULL); zassert_equal(value, test_value, NULL); } #else #warning "UINT64_MAX not supported!" ztest_test_skip(); #endif } /** * @brief Test encode/decode API for unsigned 64b integers (if 64b supported) */ static void testBACnetUnsigned64(void) { #ifdef UINT64_MAX uint8_t apdu[64] = { 0 }; uint64_t value = 0, test_value = 0; int len = 0; /* Test invalid parameter values */ len = decode_unsigned64(&apdu[0], NULL); zassert_equal(len, 8, NULL); /* TODO: How do we indicate an error? */ /* Test value zero (0) */ memset(apdu, -1, sizeof(apdu)); len = encode_unsigned64(&apdu[0], value); zassert_equal(len, 8, NULL); test_value = ~0ULL; len = decode_unsigned64(&apdu[0], &test_value); zassert_equal(len, 8, NULL); zassert_equal(value, test_value, NULL); for (value = 0x01; value != 0; value <<= 1) { len = encode_unsigned64(&apdu[0], value); zassert_equal(len, 8, NULL); test_value = ~0ULL; len = decode_unsigned64(&apdu[0], &test_value); zassert_equal(len, 8, NULL); zassert_equal(value, test_value, NULL); } #else #warning "UINT64_MAX not supported!" ztest_test_skip(); #endif } /** * @brief Test calculation of unsigned length */ static void testBACnetUnsignedLength(void) { BACNET_UNSIGNED_INTEGER value = 0; int len = 0; int bits = (8 * sizeof(BACNET_UNSIGNED_INTEGER)); for (value = ~value; value > 0; value >>= 1) { len = bacnet_unsigned_length(value); zassert_equal(len, (bits + 7)/8, NULL); bits -= 1; } len = bacnet_unsigned_length(0); zassert_equal(len, 1, NULL); } /** * @brief Test encode/decode API for signed 8b integers */ static void testBACnetSigned8(void) { uint8_t apdu[32] = { 0 }; int32_t value = 0, test_value = 0; int len = 0; /* Test invalid parameter values */ len = decode_signed8(&apdu[0], NULL); zassert_equal(len, 1, NULL); /* TODO: How do we indicate an error? */ /* Test value zero (0) */ memset(apdu, -1, sizeof(apdu)); len = encode_signed8(&apdu[0], value); zassert_equal(len, 1, NULL); test_value = ~0U; len = decode_signed8(&apdu[0], &test_value); zassert_equal(len, 1, NULL); zassert_equal(value, test_value, NULL); for (value = -127;; value++) { len = encode_signed8(&apdu[0], value); zassert_equal(len, 1, NULL); test_value = ~0U; len = decode_signed8(&apdu[0], &test_value); zassert_equal(value, test_value, NULL); if (value == 127) break; } } /** * @brief Test encode/decode API for signed 16b integers */ static void testBACnetSigned16(void) { uint8_t apdu[32] = { 0 }; int32_t value = 0, test_value = 0; int len = 0; /* Test invalid parameter values */ len = decode_signed16(&apdu[0], NULL); zassert_equal(len, 2, NULL); /* TODO: How do we indicate an error? */ /* Test value zero (0) */ memset(apdu, -1, sizeof(apdu)); len = encode_signed16(&apdu[0], value); zassert_equal(len, 2, NULL); test_value = ~0U; len = decode_signed16(&apdu[0], &test_value); zassert_equal(len, 2, NULL); zassert_equal(value, test_value, NULL); for (value = -32767;; value++) { len = encode_signed16(&apdu[0], value); zassert_equal(len, 2, NULL); test_value = ~0U; len = decode_signed16(&apdu[0], &test_value); zassert_equal(value, test_value, NULL); if (value == 32767) break; } } /** * @brief Test encode/decode API for signed 24b integers */ static void testBACnetSigned24(void) { uint8_t apdu[32] = { 0 }; int32_t value = 0, test_value = 0; int len = 0; /* Test invalid parameter values */ len = decode_signed24(&apdu[0], NULL); zassert_equal(len, 3, NULL); /* TODO: How do we indicate an error? */ /* Test value zero (0) */ memset(apdu, -1, sizeof(apdu)); len = encode_signed24(&apdu[0], value); zassert_equal(len, 3, NULL); test_value = ~0U; len = decode_signed24(&apdu[0], &test_value); zassert_equal(len, 3, NULL); zassert_equal(value, test_value, NULL); for (value = -8388607; value <= 8388607; value += 15) { len = encode_signed24(&apdu[0], value); zassert_equal(len, 3, NULL); test_value = ~0U; len = decode_signed24(&apdu[0], &test_value); zassert_equal(value, test_value, NULL); } } /** * @brief Test encode/decode API for signed 32b integers */ static void testBACnetSigned32(void) { uint8_t apdu[32] = { 0 }; int32_t value = 0, test_value = 0; int len = 0; /* Test invalid parameter values */ len = decode_signed32(&apdu[0], NULL); zassert_equal(len, 4, NULL); /* TODO: How do we indicate an error? */ /* Test value zero (0) */ memset(apdu, -1, sizeof(apdu)); len = encode_signed32(&apdu[0], value); zassert_equal(len, 4, NULL); test_value = ~0U; len = decode_signed32(&apdu[0], &test_value); zassert_equal(len, 4, NULL); zassert_equal(value, test_value, NULL); for (value = -2147483647; value < 0; value += 127) { len = encode_signed32(&apdu[0], value); zassert_equal(len, 4, NULL); test_value = ~0U; len = decode_signed32(&apdu[0], &test_value); zassert_equal(value, test_value, NULL); } for (value = 2147483647; value > 0; value -= 127) { len = encode_signed32(&apdu[0], value); zassert_equal(len, 4, NULL); test_value = ~0U; len = decode_signed32(&apdu[0], &test_value); zassert_equal(value, test_value, NULL); } } /** * @} */ void test_main(void) { ztest_test_suite(bacint_tests, ztest_unit_test(testBACnetUnsigned16), ztest_unit_test(testBACnetUnsigned24), ztest_unit_test(testBACnetUnsigned32), ztest_unit_test(testBACnetUnsigned40), ztest_unit_test(testBACnetUnsigned48), ztest_unit_test(testBACnetUnsigned56), ztest_unit_test(testBACnetUnsigned64), ztest_unit_test(testBACnetUnsignedLength), ztest_unit_test(testBACnetSigned8), ztest_unit_test(testBACnetSigned16), ztest_unit_test(testBACnetSigned24), ztest_unit_test(testBACnetSigned32) ); ztest_run_test_suite(bacint_tests); }