diff --git a/bacnet-stack/include/bacdcode.h b/bacnet-stack/include/bacdcode.h index f27b907b..0bd71fe6 100644 --- a/bacnet-stack/include/bacdcode.h +++ b/bacnet-stack/include/bacdcode.h @@ -95,8 +95,6 @@ extern "C" { /* from clause 20.2.6 Encoding of a Real Number Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ /* returns the number of apdu bytes consumed */ - int decode_real(uint8_t * apdu, float *real_value); - int encode_bacnet_real(float value, uint8_t * apdu); int encode_application_real(uint8_t * apdu, float value); int encode_context_real(uint8_t * apdu, int tag_number, float value); diff --git a/bacnet-stack/include/bacreal.h b/bacnet-stack/include/bacreal.h new file mode 100644 index 00000000..1e8a81be --- /dev/null +++ b/bacnet-stack/include/bacreal.h @@ -0,0 +1,59 @@ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2007 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ +#ifndef BACREAL_H +#define BACREAL_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + int decode_real(uint8_t * apdu, float *real_value); + int encode_bacnet_real(float value, uint8_t * apdu); + +#ifdef TEST +#include "ctest.h" + + void testBACreal(Test * pTest); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/bacnet-stack/src/bacdcode/bacdcode.c b/bacnet-stack/src/bacdcode/bacdcode.c index 7380da7a..a0c38319 100644 --- a/bacnet-stack/src/bacdcode/bacdcode.c +++ b/bacnet-stack/src/bacdcode/bacdcode.c @@ -1030,6 +1030,35 @@ int encode_context_signed(uint8_t * apdu, int tag_number, int32_t value) return len; } +* from clause 20.2.6 Encoding of a Real Number Value */ +/* and 20.2.1 General Rules for Encoding BACnet Tags */ +/* returns the number of apdu bytes consumed */ +int encode_application_real(uint8_t * apdu, float value) +{ + int len = 0; + + /* assumes that the tag only consumes 1 octet */ + len = encode_bacnet_real(value, &apdu[1]); + len += encode_tag(&apdu[0], BACNET_APPLICATION_TAG_REAL, false, len); + + return len; +} + +int encode_context_real(uint8_t * apdu, int tag_number, float value) +{ + int len = 0; + + /* assumes that the tag only consumes 1 octet */ + len = encode_bacnet_real(value, &apdu[1]); + /* we only reserved 1 byte for encoding the tag - check the limits */ + if (tag_number <= 14) + len += encode_tag(&apdu[0], (uint8_t) tag_number, true, len); + else + len = 0; + + return len; +} + /* from clause 20.2.13 Encoding of a Time Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ /* returns the number of apdu bytes consumed */ @@ -1337,6 +1366,39 @@ void testBACDCodeEnumerated(Test * pTest) return; } +void testBACDCodeReal(Test * pTest) +{ + uint8_t real_array[4] = { 0 }; + uint8_t encoded_array[4] = { 0 }; + float value = 42.123; + float decoded_value = 0; + uint8_t apdu[MAX_APDU] = { 0 }; + int len = 0, apdu_len = 0; + uint8_t tag_number = 0; + uint32_t long_value = 0; + + encode_bacnet_real(value, &real_array[0]); + decode_real(&real_array[0], &decoded_value); + ct_test(pTest, decoded_value == value); + encode_bacnet_real(value, &encoded_array[0]); + ct_test(pTest, memcmp(&real_array, &encoded_array, + sizeof(real_array)) == 0); + + /* a real will take up 4 octects plus a one octet tag */ + apdu_len = encode_application_real(&apdu[0], value); + ct_test(pTest, apdu_len == 5); + /* len tells us how many octets were used for encoding the value */ + len = decode_tag_number_and_value(&apdu[0], &tag_number, &long_value); + ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_REAL); + ct_test(pTest, decode_is_context_specific(&apdu[0]) == false); + ct_test(pTest, len == 1); + ct_test(pTest, long_value == 4); + decode_real(&apdu[len], &decoded_value); + ct_test(pTest, decoded_value == value); + + return; +} + void testBACDCodeUnsignedValue(Test * pTest, uint32_t value) { uint8_t array[5] = { 0 }; diff --git a/bacnet-stack/src/bacdcode/bacreal.c b/bacnet-stack/src/bacdcode/bacreal.c index 57b167e6..d5bd5018 100644 --- a/bacnet-stack/src/bacdcode/bacreal.c +++ b/bacnet-stack/src/bacdcode/bacreal.c @@ -100,31 +100,44 @@ int encode_bacnet_real(float value, uint8_t * apdu) return 4; } -/* from clause 20.2.6 Encoding of a Real Number Value */ -/* and 20.2.1 General Rules for Encoding BACnet Tags */ -/* returns the number of apdu bytes consumed */ -int encode_application_real(uint8_t * apdu, float value) +/* end of decoding_encoding.c */ +#ifdef TEST +#include +#include +#include +#include "ctest.h" + +void testBACreal(Test * pTest) { - int len = 0; - - /* assumes that the tag only consumes 1 octet */ - len = encode_bacnet_real(value, &apdu[1]); - len += encode_tag(&apdu[0], BACNET_APPLICATION_TAG_REAL, false, len); - - return len; + float real_value = 3.14159F, test_real_value = 0.0; + uint8_t apdu[MAX_APDU] = { 0 }; + int len = 0, test_len = 0; + + len = encode_bacnet_real(real_value, &apdu[0]); + ct_test(pTest, len == 4); + test_len = decode_real(&apdu[0], &test_real_value); + ct_test(pTest, test_len == len); } -int encode_context_real(uint8_t * apdu, int tag_number, float value) +#ifdef TEST_BACNET_REAL +int main(void) { - int len = 0; + Test *pTest; + bool rc; - /* assumes that the tag only consumes 1 octet */ - len = encode_bacnet_real(value, &apdu[1]); - /* we only reserved 1 byte for encoding the tag - check the limits */ - if (tag_number <= 14) - len += encode_tag(&apdu[0], (uint8_t) tag_number, true, len); - else - len = 0; + pTest = ct_create("BACreal", NULL); + /* individual tests */ + rc = ct_addTestFunction(pTest, testBACreal); + assert(rc); - return len; + /* configure output */ + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + ct_destroy(pTest); + + return 0; } +#endif /* TEST_BACNET_REAL */ +#endif /* TEST */ +