Bugfix/bacnet real endian simplify (#89)
* Remove dependence on endian define * Make use of existing big_endian function if BACNET_BIG_ENDIAN is not defined * Add efficient endian macro option if available Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
*.log
|
||||
*.a
|
||||
*.o
|
||||
*.exe
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ A-2: MS/TP works correctly as of the 0.2.6 release. I spent a several days corre
|
||||
|
||||
Q-3: Does the stack have some specific requirements regarding the hardware (e.g. non-volatile memory, 32-bit CPU, ...)?
|
||||
|
||||
A-3: Not really. The specific stuff is in the ports/ directory, and that is expected to be modified by the end user if necessary. Big Endian and Little Endian used to be automatic, but that took up too much code space, so there is a BIG_ENDIAN define in the makefile. Most of the variables are defined using the ANSI C-99 uint8_t, uint16_t, uint32_t, int8_t, int16_t, int32_t from stdint.h, along with bool from stdbool.h. Most of the APDU size returns are int.
|
||||
A-3: Not really. The specific stuff is in the ports/ directory, and that is expected to be modified by the end user if necessary. Most of the variables are defined using the ANSI C-99 uint8_t, uint16_t, uint32_t, int8_t, int16_t, int32_t from stdint.h, along with bool from stdbool.h. Most of the APDU size returns are int.
|
||||
|
||||
Q-4: Does the stack have some specific requirements regarding OS? What OS features are used (threads, timers, semaphors, events, mutexes...)?
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ Q. Are there some global configuration options for this BACnet stack?
|
||||
A. The BACnet stack uses some preprocessor defines to configure
|
||||
a number of subtle personalities.
|
||||
PRINT_ENABLED=1 - enables printing to stdio
|
||||
BIG_ENDIAN=0 - chooses the BACnet encoding and decoding order
|
||||
BACDL_BIP=1 - chooses BACnet/IP for the datalink layer
|
||||
BACDL_ETHERNET=0 - chooses BACnet Ethernet for the datalink layer
|
||||
BACDL_ARCNET=0 - chooses BACnet ARCNET for the datalink layer
|
||||
|
||||
@@ -256,7 +256,6 @@
|
||||
<name>CCDefines</name>
|
||||
<state>BACDL_MSTP=1</state>
|
||||
<state>MAX_APDU=50</state>
|
||||
<state>BIG_ENDIAN=0</state>
|
||||
<state>MAX_TSM_TRANSACTIONS=0</state>
|
||||
<state>BACAPP_REAL</state>
|
||||
<state>BACAPP_UNSIGNED</state>
|
||||
@@ -1318,7 +1317,6 @@
|
||||
<state>NDEBUG</state>
|
||||
<state>BACDL_MSTP</state>
|
||||
<state>MAX_APDU=50</state>
|
||||
<state>BIG_ENDIAN=0</state>
|
||||
<state>MAX_TSM_TRANSACTIONS=0</state>
|
||||
<state>BACAPP_REAL</state>
|
||||
<state>BACAPP_UNSIGNED</state>
|
||||
|
||||
@@ -102,7 +102,6 @@ Preprocessor
|
||||
Defined symbols:
|
||||
BACDL_MSTP
|
||||
MAX_APDU=50
|
||||
BIG_ENDIAN=0
|
||||
MAX_TSM_TRANSACTIONS=0
|
||||
BACAPP_REAL
|
||||
BACAPP_UNSIGNED
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
<ListValues>
|
||||
<Value>BACDL_MSTP</Value>
|
||||
<Value>MAX_APDU=128</Value>
|
||||
<Value>BIG_ENDIAN=0</Value>
|
||||
<Value>MAX_TSM_TRANSACTIONS=0</Value>
|
||||
<Value>MSTP_PDU_PACKET_COUNT=2</Value>
|
||||
<Value>MAX_CHARACTER_STRING_BYTES=64</Value>
|
||||
@@ -108,7 +107,6 @@
|
||||
<ListValues>
|
||||
<Value>BACDL_MSTP</Value>
|
||||
<Value>MAX_APDU=128</Value>
|
||||
<Value>BIG_ENDIAN=0</Value>
|
||||
<Value>MAX_TSM_TRANSACTIONS=0</Value>
|
||||
<Value>MSTP_PDU_PACKET_COUNT=2</Value>
|
||||
<Value>MAX_CHARACTER_STRING_BYTES=64</Value>
|
||||
|
||||
@@ -257,7 +257,6 @@
|
||||
<state>BACDL_MSTP</state>
|
||||
<state>MAX_ANALOG_INPUTS=100</state>
|
||||
<state>MAX_APDU=50</state>
|
||||
<state>BIG_ENDIAN=0</state>
|
||||
<state>MAX_TSM_TRANSACTIONS=0</state>
|
||||
<state>MSTP_PDU_PACKET_COUNT=2</state>
|
||||
<state>MAX_CHARACTER_STRING_BYTES=64</state>
|
||||
@@ -1323,7 +1322,6 @@
|
||||
<state>NDEBUG</state>
|
||||
<state>BACDL_MSTP</state>
|
||||
<state>MAX_APDU=128</state>
|
||||
<state>BIG_ENDIAN=0</state>
|
||||
<state>MAX_TSM_TRANSACTIONS=0</state>
|
||||
<state>MSTP_PDU_PACKET_COUNT=2</state>
|
||||
<state>MAX_CHARACTER_STRING_BYTES=64</state>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!DOCTYPE CrossStudio_Project_File>
|
||||
<solution Name="bacnet" version="2">
|
||||
<project Name="bacnet">
|
||||
<configuration Name="Common" Platform="AVR" Target="ATmega644P" avr_architecture="V2E" avr_debug_interface="JTAG" avr_flash_size="128K" build_use_hardware_multiplier="Yes" c_preprocessor_definitions="BACDL_MSTP;MAX_APDU=128;BIG_ENDIAN=0;MAX_TSM_TRANSACTIONS=0;MAX_CHARACTER_STRING_BYTES=64;MAX_OCTET_STRING_BYTES=64;BACAPP_BOOLEAN;BACAPP_REAL;BACAPP_OBJECT_ID;BACAPP_UNSIGNED;BACAPP_ENUMERATED;BACAPP_CHARACTER_STRING;WRITE_PROPERTY" c_user_include_directories="$(ProjectDir);$(ProjectDir)/crossworks;$(ProjectDir)/../../include;$(ProjectDir)/../../src" linker_call_stack_size="1024" linker_memory_map_file="$(PackagesDir)/targets/avr/ATmega644P.xml" project_directory="" project_type="Executable"/>
|
||||
<configuration Name="Common" Platform="AVR" Target="ATmega644P" avr_architecture="V2E" avr_debug_interface="JTAG" avr_flash_size="128K" build_use_hardware_multiplier="Yes" c_preprocessor_definitions="BACDL_MSTP;MAX_APDU=128;MAX_TSM_TRANSACTIONS=0;MAX_CHARACTER_STRING_BYTES=64;MAX_OCTET_STRING_BYTES=64;BACAPP_BOOLEAN;BACAPP_REAL;BACAPP_OBJECT_ID;BACAPP_UNSIGNED;BACAPP_ENUMERATED;BACAPP_CHARACTER_STRING;WRITE_PROPERTY" c_user_include_directories="$(ProjectDir);$(ProjectDir)/crossworks;$(ProjectDir)/../../include;$(ProjectDir)/../../src" linker_call_stack_size="1024" linker_memory_map_file="$(PackagesDir)/targets/avr/ATmega644P.xml" project_directory="" project_type="Executable"/>
|
||||
<folder Name="Source Files">
|
||||
<configuration Name="Common" filter="c;h;s;asm;inc;s90"/>
|
||||
<file file_name="adc.c">
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE CrossStudio_Session_File>
|
||||
<session>
|
||||
<Bookmarks/>
|
||||
<Breakpoints groups="Breakpoints" active_group="Breakpoints"/>
|
||||
<ExecutionProfileWindow/>
|
||||
<FrameBufferWindow>
|
||||
<FrameBufferWindow bufferHeight="-1" addressSpace="" addressText="" bufferWidth="-1"/>
|
||||
</FrameBufferWindow>
|
||||
<Memory1/>
|
||||
<Memory2/>
|
||||
<Memory3/>
|
||||
<Memory4/>
|
||||
<Project>
|
||||
<ProjectSessionItem path="bacnet"/>
|
||||
<ProjectSessionItem path="bacnet;bacnet"/>
|
||||
</Project>
|
||||
<Register1/>
|
||||
<Register2/>
|
||||
<Register3/>
|
||||
<Register4/>
|
||||
<TargetWindow programLoadAddress="" programSize="" uploadStartAddress="" programMemoryInterface="" programFileName="" uploadMemoryInterface="" programFileType="" uploadFileName="" uploadFileType="" programAction="" uploadSize=""/>
|
||||
<Threads>
|
||||
<ThreadsWindow showLists=""/>
|
||||
</Threads>
|
||||
<TraceWindow>
|
||||
<Trace enabled="Yes"/>
|
||||
</TraceWindow>
|
||||
<Watch1>
|
||||
<Watches active="1" update="Never"/>
|
||||
</Watch1>
|
||||
<Watch2>
|
||||
<Watches active="0" update="Never"/>
|
||||
</Watch2>
|
||||
<Watch3>
|
||||
<Watches active="0" update="Never"/>
|
||||
</Watch3>
|
||||
<Watch4>
|
||||
<Watches active="0" update="Never"/>
|
||||
</Watch4>
|
||||
<Files/>
|
||||
<ARMCrossStudioWindow activeProject="bacnet" fileDialogDefaultFilter="*.c" autoConnectTarget="" buildConfiguration="Common" sessionSettings="" debugSearchFileMap="" fileDialogInitialDirectory="" debugSearchPath="" autoConnectCapabilities="0"/>
|
||||
</session>
|
||||
@@ -135,7 +135,7 @@
|
||||
value="..\;..\..\..\include;..\..\..\demo\object"/>
|
||||
<property key="optimization-master" value="Enable all"/>
|
||||
<property key="preprocessor-macros"
|
||||
value="PRINT_ENABLED=0;BACDL_MSTP=1;BIG_ENDIAN=0;MAX_APDU=50;MAX_TSM_TRANSACTIONS=0;BACAPP_MINIMAL"/>
|
||||
value="PRINT_ENABLED=0;BACDL_MSTP=1;MAX_APDU=50;MAX_TSM_TRANSACTIONS=0;BACAPP_MINIMAL"/>
|
||||
<property key="procedural-abstraction-passes" value="0"/>
|
||||
<property key="storage-class" value="sca"/>
|
||||
<property key="verbose" value="false"/>
|
||||
|
||||
@@ -269,7 +269,7 @@ suite_state=
|
||||
[TOOL_SETTINGS]
|
||||
TS{DD2213A8-6310-47B1-8376-9430CDFC013F}=
|
||||
TS{BFD27FBA-4A02-4C0E-A5E5-B812F3E7707C}=/m"$(BINDIR_)$(TARGETBASE).map" /o"$(TARGETBASE).cof"
|
||||
TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}=-DPRINT_ENABLED=0 -DBACDL_MSTP=1 -DBIG_ENDIAN=0 -DMAX_APDU=50 -DMAX_TSM_TRANSACTIONS=0 -mL -Ls -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
|
||||
TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}=-DPRINT_ENABLED=0 -DBACDL_MSTP=1 -DMAX_APDU=50 -DMAX_TSM_TRANSACTIONS=0 -mL -Ls -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
|
||||
TS{ADE93A55-C7C7-4D4D-A4BA-59305F7D0391}=
|
||||
[INSTRUMENTED_TRACE]
|
||||
enable=0
|
||||
|
||||
@@ -31,7 +31,6 @@ MPLAB C18 Tab: General: Macro Definitions:
|
||||
PRINT_ENABLED=0
|
||||
BACDL_MSTP=1
|
||||
TSM_ENABLED=0
|
||||
BIG_ENDIAN=0
|
||||
|
||||
3. The linker script must reserve some extra stack space.
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@
|
||||
value="..\;..\..\..\include;..\..\..\demo\object"/>
|
||||
<property key="optimization-master" value="Enable all"/>
|
||||
<property key="preprocessor-macros"
|
||||
value="PRINT_ENABLED=0;BACDL_MSTP=1;BIG_ENDIAN=0;MAX_APDU=50;MAX_TSM_TRANSACTIONS=0;BACAPP_MINIMAL"/>
|
||||
value="PRINT_ENABLED=0;BACDL_MSTP=1;MAX_APDU=50;MAX_TSM_TRANSACTIONS=0;BACAPP_MINIMAL"/>
|
||||
<property key="procedural-abstraction-passes" value="0"/>
|
||||
<property key="storage-class" value="sca"/>
|
||||
<property key="verbose" value="false"/>
|
||||
|
||||
@@ -31,7 +31,6 @@ MPLAB C18 Tab: General: Macro Definitions:
|
||||
PRINT_ENABLED=0
|
||||
BACDL_MSTP=1
|
||||
TSM_ENABLED=0
|
||||
BIG_ENDIAN=0
|
||||
|
||||
3. The linker script must reserve some extra stack space.
|
||||
|
||||
|
||||
@@ -228,7 +228,6 @@
|
||||
<state>USE_STDPERIPH_DRIVER</state>
|
||||
<state>BACDL_MSTP</state>
|
||||
<state>MAX_APDU=480</state>
|
||||
<state>BIG_ENDIAN=0</state>
|
||||
<state>MAX_TSM_TRANSACTIONS=0</state>
|
||||
<state>BACAPP_BOOLEAN</state>
|
||||
<state>BACAPP_REAL</state>
|
||||
|
||||
@@ -2023,6 +2023,20 @@ int encode_context_real(uint8_t *apdu, uint8_t tag_number, float value)
|
||||
return len;
|
||||
}
|
||||
|
||||
int decode_context_real(uint8_t *apdu, uint8_t tag_number, float *real_value)
|
||||
{
|
||||
uint32_t len_value;
|
||||
int len = 0;
|
||||
|
||||
if (decode_is_context_tag(&apdu[len], tag_number)) {
|
||||
len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
|
||||
len += decode_real(&apdu[len], real_value);
|
||||
} else {
|
||||
len = -1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
#if BACNET_USE_DOUBLE
|
||||
/* from clause 20.2.7 Encoding of a Double Precision Real Number Value */
|
||||
/* and 20.2.1 General Rules for Encoding BACnet Tags */
|
||||
@@ -2050,6 +2064,20 @@ int encode_context_double(uint8_t *apdu, uint8_t tag_number, double value)
|
||||
|
||||
return len;
|
||||
}
|
||||
int decode_context_double(
|
||||
uint8_t *apdu, uint8_t tag_number, double *double_value)
|
||||
{
|
||||
uint32_t len_value;
|
||||
int len = 0;
|
||||
|
||||
if (decode_is_context_tag(&apdu[len], tag_number)) {
|
||||
len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
|
||||
len += decode_double(&apdu[len], double_value);
|
||||
} else {
|
||||
len = -1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* from clause 20.2.13 Encoding of a Time Value */
|
||||
|
||||
@@ -182,6 +182,11 @@ extern "C" {
|
||||
uint8_t * apdu,
|
||||
uint8_t tag_number,
|
||||
float value);
|
||||
BACNET_STACK_EXPORT
|
||||
int decode_context_real(
|
||||
uint8_t * apdu,
|
||||
uint8_t tag_number,
|
||||
float *real_value);
|
||||
|
||||
/* from clause 20.2.7 Encoding of a Double Precision Real Number Value */
|
||||
/* and 20.2.1 General Rules for Encoding BACnet Tags */
|
||||
@@ -196,6 +201,11 @@ extern "C" {
|
||||
uint8_t * apdu,
|
||||
uint8_t tag_number,
|
||||
double value);
|
||||
BACNET_STACK_EXPORT
|
||||
int decode_context_double(
|
||||
uint8_t * apdu,
|
||||
uint8_t tag_number,
|
||||
double *double_value);
|
||||
|
||||
/* from clause 20.2.14 Encoding of an Object Identifier Value */
|
||||
/* and 20.2.1 General Rules for Encoding BACnet Tags */
|
||||
|
||||
+15
-105
@@ -41,13 +41,10 @@
|
||||
#include "bacnet/bacstr.h"
|
||||
#include "bacnet/bacint.h"
|
||||
#include "bacnet/bacreal.h"
|
||||
#include "bacnet/basic/sys/bigend.h"
|
||||
|
||||
/** @file bacreal.c Encode/Decode Floating Point (Real) Types */
|
||||
|
||||
/* NOTE: byte order plays a role in decoding multibyte values */
|
||||
/* http://www.unixpapa.com/incnote/byteorder.html */
|
||||
#ifndef BIG_ENDIAN
|
||||
#error Define BIG_ENDIAN=0 or BIG_ENDIAN=1 for BACnet Stack in compiler settings
|
||||
#ifndef BACNET_USE_DOUBLE
|
||||
#define BACNET_USE_DOUBLE 1
|
||||
#endif
|
||||
|
||||
/* from clause 20.2.6 Encoding of a Real Number Value */
|
||||
@@ -60,17 +57,17 @@ int decode_real(uint8_t *apdu, float *real_value)
|
||||
} my_data;
|
||||
|
||||
/* NOTE: assumes the compiler stores float as IEEE-754 float */
|
||||
#if BIG_ENDIAN
|
||||
if (big_endian()) {
|
||||
my_data.byte[0] = apdu[0];
|
||||
my_data.byte[1] = apdu[1];
|
||||
my_data.byte[2] = apdu[2];
|
||||
my_data.byte[3] = apdu[3];
|
||||
#else
|
||||
} else {
|
||||
my_data.byte[0] = apdu[3];
|
||||
my_data.byte[1] = apdu[2];
|
||||
my_data.byte[2] = apdu[1];
|
||||
my_data.byte[3] = apdu[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
*real_value = my_data.real_value;
|
||||
|
||||
@@ -87,20 +84,6 @@ int decode_real_safe(uint8_t *apdu, uint32_t len_value, float *real_value)
|
||||
}
|
||||
}
|
||||
|
||||
int decode_context_real(uint8_t *apdu, uint8_t tag_number, float *real_value)
|
||||
{
|
||||
uint32_t len_value;
|
||||
int len = 0;
|
||||
|
||||
if (decode_is_context_tag(&apdu[len], tag_number)) {
|
||||
len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
|
||||
len += decode_real(&apdu[len], real_value);
|
||||
} else {
|
||||
len = -1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/* from clause 20.2.6 Encoding of a Real Number Value */
|
||||
/* returns the number of apdu bytes consumed */
|
||||
int encode_bacnet_real(float value, uint8_t *apdu)
|
||||
@@ -112,17 +95,17 @@ int encode_bacnet_real(float value, uint8_t *apdu)
|
||||
|
||||
/* NOTE: assumes the compiler stores float as IEEE-754 float */
|
||||
my_data.real_value = value;
|
||||
#if BIG_ENDIAN
|
||||
if (big_endian()) {
|
||||
apdu[0] = my_data.byte[0];
|
||||
apdu[1] = my_data.byte[1];
|
||||
apdu[2] = my_data.byte[2];
|
||||
apdu[3] = my_data.byte[3];
|
||||
#else
|
||||
} else {
|
||||
apdu[0] = my_data.byte[3];
|
||||
apdu[1] = my_data.byte[2];
|
||||
apdu[2] = my_data.byte[1];
|
||||
apdu[3] = my_data.byte[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
@@ -139,7 +122,7 @@ int decode_double(uint8_t *apdu, double *double_value)
|
||||
} my_data;
|
||||
|
||||
/* NOTE: assumes the compiler stores float as IEEE-754 float */
|
||||
#if BIG_ENDIAN
|
||||
if (big_endian()) {
|
||||
my_data.byte[0] = apdu[0];
|
||||
my_data.byte[1] = apdu[1];
|
||||
my_data.byte[2] = apdu[2];
|
||||
@@ -148,7 +131,7 @@ int decode_double(uint8_t *apdu, double *double_value)
|
||||
my_data.byte[5] = apdu[5];
|
||||
my_data.byte[6] = apdu[6];
|
||||
my_data.byte[7] = apdu[7];
|
||||
#else
|
||||
} else {
|
||||
my_data.byte[0] = apdu[7];
|
||||
my_data.byte[1] = apdu[6];
|
||||
my_data.byte[2] = apdu[5];
|
||||
@@ -157,8 +140,7 @@ int decode_double(uint8_t *apdu, double *double_value)
|
||||
my_data.byte[5] = apdu[2];
|
||||
my_data.byte[6] = apdu[1];
|
||||
my_data.byte[7] = apdu[0];
|
||||
#endif
|
||||
|
||||
}
|
||||
*double_value = my_data.double_value;
|
||||
|
||||
return 8;
|
||||
@@ -185,7 +167,7 @@ int encode_bacnet_double(double value, uint8_t *apdu)
|
||||
|
||||
/* NOTE: assumes the compiler stores float as IEEE-754 float */
|
||||
my_data.double_value = value;
|
||||
#if BIG_ENDIAN
|
||||
if (big_endian()) {
|
||||
apdu[0] = my_data.byte[0];
|
||||
apdu[1] = my_data.byte[1];
|
||||
apdu[2] = my_data.byte[2];
|
||||
@@ -194,7 +176,7 @@ int encode_bacnet_double(double value, uint8_t *apdu)
|
||||
apdu[5] = my_data.byte[5];
|
||||
apdu[6] = my_data.byte[6];
|
||||
apdu[7] = my_data.byte[7];
|
||||
#else
|
||||
} else {
|
||||
apdu[0] = my_data.byte[7];
|
||||
apdu[1] = my_data.byte[6];
|
||||
apdu[2] = my_data.byte[5];
|
||||
@@ -203,80 +185,8 @@ int encode_bacnet_double(double value, uint8_t *apdu)
|
||||
apdu[5] = my_data.byte[2];
|
||||
apdu[6] = my_data.byte[1];
|
||||
apdu[7] = my_data.byte[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
int decode_context_double(
|
||||
uint8_t *apdu, uint8_t tag_number, double *double_value)
|
||||
{
|
||||
uint32_t len_value;
|
||||
int len = 0;
|
||||
|
||||
if (decode_is_context_tag(&apdu[len], tag_number)) {
|
||||
len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
|
||||
len += decode_double(&apdu[len], double_value);
|
||||
} else {
|
||||
len = -1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* end of decoding_encoding.c */
|
||||
#ifdef TEST
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "ctest.h"
|
||||
|
||||
void testBACreal(Test *pTest)
|
||||
{
|
||||
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);
|
||||
ct_test(pTest, test_real_value == real_value);
|
||||
}
|
||||
|
||||
void testBACdouble(Test *pTest)
|
||||
{
|
||||
double double_value = 3.1415927, test_double_value = 0.0;
|
||||
uint8_t apdu[MAX_APDU] = { 0 };
|
||||
int len = 0, test_len = 0;
|
||||
|
||||
len = encode_bacnet_double(double_value, &apdu[0]);
|
||||
ct_test(pTest, len == 8);
|
||||
test_len = decode_double(&apdu[0], &test_double_value);
|
||||
ct_test(pTest, test_len == len);
|
||||
ct_test(pTest, test_double_value == double_value);
|
||||
}
|
||||
|
||||
#ifdef TEST_BACNET_REAL
|
||||
int main(void)
|
||||
{
|
||||
Test *pTest;
|
||||
bool rc;
|
||||
|
||||
pTest = ct_create("BACreal", NULL);
|
||||
/* individual tests */
|
||||
rc = ct_addTestFunction(pTest, testBACreal);
|
||||
assert(rc);
|
||||
rc = ct_addTestFunction(pTest, testBACdouble);
|
||||
assert(rc);
|
||||
|
||||
/* configure output */
|
||||
ct_setStream(pTest, stdout);
|
||||
ct_run(pTest);
|
||||
(void)ct_report(pTest);
|
||||
ct_destroy(pTest);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* TEST_BACNET_REAL */
|
||||
#endif /* TEST */
|
||||
|
||||
@@ -45,11 +45,6 @@ extern "C" {
|
||||
float *real_value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
int decode_context_real(
|
||||
uint8_t * apdu,
|
||||
uint8_t tag_number,
|
||||
float *real_value);
|
||||
BACNET_STACK_EXPORT
|
||||
int encode_bacnet_real(
|
||||
float value,
|
||||
uint8_t * apdu);
|
||||
@@ -58,11 +53,6 @@ extern "C" {
|
||||
uint8_t * apdu,
|
||||
double *real_value);
|
||||
BACNET_STACK_EXPORT
|
||||
int decode_context_double(
|
||||
uint8_t * apdu,
|
||||
uint8_t tag_number,
|
||||
double *double_value);
|
||||
BACNET_STACK_EXPORT
|
||||
int decode_double_safe(
|
||||
uint8_t * apdu,
|
||||
uint32_t len_value,
|
||||
@@ -73,17 +63,6 @@ extern "C" {
|
||||
double value,
|
||||
uint8_t * apdu);
|
||||
|
||||
#ifdef TEST
|
||||
#include "ctest.h"
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void testBACreal(
|
||||
Test * pTest);
|
||||
BACNET_STACK_EXPORT
|
||||
void testBACdouble(
|
||||
Test * pTest);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
|
||||
/** @file bigend.c Determination of Endianess */
|
||||
|
||||
#include "bigend.h"
|
||||
#include "bacnet/basic/sys/bigend.h"
|
||||
|
||||
#ifndef BACNET_BIG_ENDIAN
|
||||
/* Big-Endian systems save the most significant byte first. */
|
||||
/* Sun and Motorola processors, IBM-370s and PDP-10s are big-endian. */
|
||||
/* "Network Byte Order" is also know as "Big-Endian Byte Order" */
|
||||
@@ -46,3 +47,4 @@ int big_endian(void)
|
||||
|
||||
return (u.c[sizeof(long) - 1] == 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -29,26 +29,24 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#ifndef BACNET_BIG_ENDIAN
|
||||
/* GCC */
|
||||
#ifdef __BYTE_ORDER__
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
#define BACNET_BIG_ENDIAN 1
|
||||
#else
|
||||
#define BACNET_BIG_ENDIAN 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Big-Endian systems save the most significant byte first. */
|
||||
/* Sun and Motorola processors, IBM-370s and PDP-10s are big-endian. */
|
||||
/* for example, a 4 byte integer 67305985 is 0x04030201 in hexidecimal. */
|
||||
/* x[0] = 0x04 */
|
||||
/* x[1] = 0x03 */
|
||||
/* x[2] = 0x02 */
|
||||
/* x[3] = 0x01 */
|
||||
|
||||
/* Little-Endian systems save the least significant byte first. */
|
||||
/* The entire Intel x86 family, Vaxes, Alphas and PDP-11s are little-endian. */
|
||||
/* for example, a 4 byte integer 67305985 is 0x04030201 in hexidecimal. */
|
||||
/* x[0] = 0x01 */
|
||||
/* x[1] = 0x02 */
|
||||
/* x[2] = 0x03 */
|
||||
/* x[3] = 0x04 */
|
||||
|
||||
#ifdef BACNET_BIG_ENDIAN
|
||||
#define big_endian() BACNET_BIG_ENDIAN
|
||||
#else
|
||||
BACNET_STACK_EXPORT
|
||||
int big_endian(
|
||||
void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -68,14 +68,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Define your processor architecture as
|
||||
Big Endian (PowerPC,68K,Sparc) or Little Endian (Intel,AVR)
|
||||
ARM and MIPS can be either - what is your setup? */
|
||||
#if !defined(BIG_ENDIAN)
|
||||
#define BIG_ENDIAN 0
|
||||
#endif
|
||||
|
||||
/* Define your Vendor Identifier assigned by ASHRAE */
|
||||
#if !defined(BACNET_VENDOR_ID)
|
||||
#define BACNET_VENDOR_ID 260
|
||||
|
||||
@@ -61,6 +61,11 @@ bacint: logfile bacint.mak
|
||||
( ./bacint >> ${LOGFILE} )
|
||||
$(MAKE) -s -f bacint.mak clean
|
||||
|
||||
bacreal: logfile bacnet/bacreal/Makefile
|
||||
$(MAKE) -s -C bacnet/bacreal/ clean all
|
||||
( ./bacnet/bacreal/unittest >> ${LOGFILE} )
|
||||
$(MAKE) -s -C bacnet/bacreal/ clean
|
||||
|
||||
bacstr: logfile bacstr.mak
|
||||
$(MAKE) -s -f bacstr.mak clean all
|
||||
( ./bacstr >> ${LOGFILE} )
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#Makefile to build test case
|
||||
CC = gcc
|
||||
SRC_DIR = ../../../src
|
||||
TEST_DIR = ../../../test
|
||||
INCLUDES = -I$(SRC_DIR) -I$(TEST_DIR)
|
||||
DEFINES = -DDEBUG_ENABLED=0
|
||||
|
||||
CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g
|
||||
|
||||
SRCS = main.c \
|
||||
$(SRC_DIR)/bacnet/bacreal.c \
|
||||
$(SRC_DIR)/bacnet/basic/sys/bigend.c \
|
||||
$(TEST_DIR)/ctest.c
|
||||
|
||||
TARGET_NAME = unittest
|
||||
ifeq ($(OS),Windows_NT)
|
||||
TARGET_EXT = .exe
|
||||
else
|
||||
TARGET_EXT =
|
||||
endif
|
||||
TARGET = $(TARGET_NAME)$(TARGET_EXT)
|
||||
|
||||
all: ${TARGET}
|
||||
|
||||
OBJS = ${SRCS:.c=.o}
|
||||
|
||||
${TARGET}: ${OBJS}
|
||||
${CC} -o $@ ${OBJS}
|
||||
|
||||
.c.o:
|
||||
${CC} -c ${CFLAGS} $*.c -o $@
|
||||
|
||||
depend:
|
||||
rm -f .depend
|
||||
${CC} -MM ${CFLAGS} *.c >> .depend
|
||||
|
||||
clean:
|
||||
rm -rf ${TARGET} $(OBJS)
|
||||
|
||||
test: ${TARGET}
|
||||
./${TARGET}
|
||||
|
||||
include: .depend
|
||||
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Steve Karg
|
||||
* @date April 2020
|
||||
* @brief Test file for a REAL and DOUBLE encode and decode
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "bacnet/bacreal.h"
|
||||
#include "ctest.h"
|
||||
|
||||
static void test_setup(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void test_cleanup(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void testBACreal(Test *pTest)
|
||||
{
|
||||
float real_value = 3.14159F, test_real_value = 0.0;
|
||||
uint8_t apdu[50] = { 0 };
|
||||
int len = 0, test_len = 0;
|
||||
|
||||
test_setup();
|
||||
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);
|
||||
ct_test(pTest, test_real_value == real_value);
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
void testBACdouble(Test *pTest)
|
||||
{
|
||||
double double_value = 3.1415927, test_double_value = 0.0;
|
||||
uint8_t apdu[50] = { 0 };
|
||||
int len = 0, test_len = 0;
|
||||
|
||||
test_setup();
|
||||
len = encode_bacnet_double(double_value, &apdu[0]);
|
||||
ct_test(pTest, len == 8);
|
||||
test_len = decode_double(&apdu[0], &test_double_value);
|
||||
ct_test(pTest, test_len == len);
|
||||
ct_test(pTest, test_double_value == double_value);
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Test *pTest;
|
||||
bool rc;
|
||||
|
||||
pTest = ct_create("BACreal", NULL);
|
||||
/* individual tests */
|
||||
rc = ct_addTestFunction(pTest, testBACreal);
|
||||
assert(rc);
|
||||
rc = ct_addTestFunction(pTest, testBACdouble);
|
||||
assert(rc);
|
||||
|
||||
/* configure output */
|
||||
ct_setStream(pTest, stdout);
|
||||
ct_run(pTest);
|
||||
(void)ct_report(pTest);
|
||||
ct_destroy(pTest);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user