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:
Steve Karg
2020-05-24 09:36:21 -05:00
committed by GitHub
parent 764e0e8448
commit cbfa74e48d
25 changed files with 354 additions and 257 deletions
+2 -1
View File
@@ -1,3 +1,4 @@
*.log
*.a *.a
*.o *.o
*.exe *.exe
@@ -63,4 +64,4 @@ address_cache
/build/* /build/*
/_build/* /_build/*
CMakeLists.txt.user CMakeLists.txt.user
/out/* /out/*
+1 -1
View File
@@ -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, ...)? 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...)? Q-4: Does the stack have some specific requirements regarding OS? What OS features are used (threads, timers, semaphors, events, mutexes...)?
+13 -14
View File
@@ -1,7 +1,7 @@
BACnet Stack - SourceForge.net BACnet Stack - SourceForge.net
Build for Visual C++ 6.0 Build for Visual C++ 6.0
When building the BACnet stack using Visual C++ compiler, When building the BACnet stack using Visual C++ compiler,
there are some settings that are important. there are some settings that are important.
Q. Are there some global configuration options for this BACnet stack? Q. Are there some global configuration options for this BACnet stack?
@@ -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. The BACnet stack uses some preprocessor defines to configure
a number of subtle personalities. a number of subtle personalities.
PRINT_ENABLED=1 - enables printing to stdio 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_BIP=1 - chooses BACnet/IP for the datalink layer
BACDL_ETHERNET=0 - chooses BACnet Ethernet for the datalink layer BACDL_ETHERNET=0 - chooses BACnet Ethernet for the datalink layer
BACDL_ARCNET=0 - chooses BACnet ARCNET for the datalink layer BACDL_ARCNET=0 - chooses BACnet ARCNET for the datalink layer
@@ -17,13 +16,13 @@ BACDL_MSTP=0 - chooses BACnet MS/TP for the datalink layer
USE_INADDR=1 - uses INADDR_BROADCAST for broadcast rather than CLASSx USE_INADDR=1 - uses INADDR_BROADCAST for broadcast rather than CLASSx
TSM_ENABLED=1 - enables the Transaction State Machine for clients TSM_ENABLED=1 - enables the Transaction State Machine for clients
BIP_DEBUG=1 - enables print statements for debugging BIP_DEBUG=1 - enables print statements for debugging
In Visual C++, add a Preprocessor Definition by: In Visual C++, add a Preprocessor Definition by:
1. Select "Project" menu 1. Select "Project" menu
2. Select "Settings..." 2. Select "Settings..."
3. Select the "C/C++" tab (3rd Tab) 3. Select the "C/C++" tab (3rd Tab)
4. Select the Category: General 4. Select the Category: General
5. You can see the "Preprocessor Definitions:" box 5. You can see the "Preprocessor Definitions:" box
6. Type OPTION_NAME=1 or OPTION_NAME=0 in that edit box 6. Type OPTION_NAME=1 or OPTION_NAME=0 in that edit box
using a comma to separate multiple options. using a comma to separate multiple options.
7. Press OK 7. Press OK
8. Compile the entire project again... 8. Compile the entire project again...
@@ -39,8 +38,8 @@ unix2dos bacnet.dsp
Q. error LNK2001: unresolved external symbol _WinMain@16 Q. error LNK2001: unresolved external symbol _WinMain@16
A. The demo ports/win32/main.c was designed as a Win32 Console A. The demo ports/win32/main.c was designed as a Win32 Console
Application. If you want to change it to a Windows GUI application, Application. If you want to change it to a Windows GUI application,
you will have to add all the Windows GUI code, including WinMain(). you will have to add all the Windows GUI code, including WinMain().
I recommend that you use a framework, such as WxWidgets/WxWindows, I recommend that you use a framework, such as WxWidgets/WxWindows,
but this has not been done yet. but this has not been done yet.
@@ -65,7 +64,7 @@ c:\code\bacnet-stack\demo\handler\,c:\code\bacnet-stack\demo\object\
Q. error C2065: 'MAX_MPDU' : undeclared identifier Q. error C2065: 'MAX_MPDU' : undeclared identifier
A. The BACnet stack uses a preprocessor define to configure A. The BACnet stack uses a preprocessor define to configure
its datalink layer. In Visual C++, add a Preprocessor Definition by: its datalink layer. In Visual C++, add a Preprocessor Definition by:
1. Select "Project" menu 1. Select "Project" menu
2. Select "Settings..." 2. Select "Settings..."
3. Select the "C/C++" tab (3rd Tab) 3. Select the "C/C++" tab (3rd Tab)
@@ -78,7 +77,7 @@ its datalink layer. In Visual C++, add a Preprocessor Definition by:
Q. error LNK2001: unresolved external symbol _bacapp_print Q. error LNK2001: unresolved external symbol _bacapp_print
A. The BACnet stack uses a preprocessor define to configure A. The BACnet stack uses a preprocessor define to configure
printing to stdio. In Visual C++, add a Preprocessor Definition by: printing to stdio. In Visual C++, add a Preprocessor Definition by:
1. Select "Project" menu 1. Select "Project" menu
2. Select "Settings..." 2. Select "Settings..."
3. Select the "C/C++" tab (3rd Tab) 3. Select the "C/C++" tab (3rd Tab)
@@ -101,8 +100,8 @@ A. Visual C++ needs to have the Winsock library to be happy:
Q. error C2061: in file tsm.c Q. error C2061: in file tsm.c
A. The BACnet stack uses a preprocessor define to configure A. The BACnet stack uses a preprocessor define to configure
client functionality in the Transaction State Machine (TSM). client functionality in the Transaction State Machine (TSM).
In Visual C++, add a Preprocessor Definition by: In Visual C++, add a Preprocessor Definition by:
1. Select "Project" menu 1. Select "Project" menu
2. Select "Settings..." 2. Select "Settings..."
3. Select the "C/C++" tab (3rd Tab) 3. Select the "C/C++" tab (3rd Tab)
@@ -130,10 +129,10 @@ with MS/TP datalink enabled (BACDL_MSTP instead of BACDL_BIP):
4. Select the Category: Code Generation 4. Select the Category: Code Generation
5. Select the Multithreaded from the "Use runtime library" box options 5. Select the Multithreaded from the "Use runtime library" box options
Q. error LNK2019: Verweis auf nicht aufgelöstes externes Symbol Q. error LNK2019: Verweis auf nicht aufgelöstes externes Symbol
"_GetAdaptersInfo@8" in Funktion "_getIpMaskForIpAddress". "_GetAdaptersInfo@8" in Funktion "_getIpMaskForIpAddress".
A. There is the Iphlpapi.lib library missing from the VC++ project A. There is the Iphlpapi.lib library missing from the VC++ project
(for the GetAdaptersInfo error) that you need to add: (for the GetAdaptersInfo error) that you need to add:
http://msdn2.microsoft.com/en-us/library/aa916102.aspx http://msdn2.microsoft.com/en-us/library/aa916102.aspx
Note that Iphlpapi.lib/.h is not included with Visual C++ 6.0; Note that Iphlpapi.lib/.h is not included with Visual C++ 6.0;
you would need to download the platform SDK to get it. you would need to download the platform SDK to get it.
-2
View File
@@ -256,7 +256,6 @@
<name>CCDefines</name> <name>CCDefines</name>
<state>BACDL_MSTP=1</state> <state>BACDL_MSTP=1</state>
<state>MAX_APDU=50</state> <state>MAX_APDU=50</state>
<state>BIG_ENDIAN=0</state>
<state>MAX_TSM_TRANSACTIONS=0</state> <state>MAX_TSM_TRANSACTIONS=0</state>
<state>BACAPP_REAL</state> <state>BACAPP_REAL</state>
<state>BACAPP_UNSIGNED</state> <state>BACAPP_UNSIGNED</state>
@@ -1318,7 +1317,6 @@
<state>NDEBUG</state> <state>NDEBUG</state>
<state>BACDL_MSTP</state> <state>BACDL_MSTP</state>
<state>MAX_APDU=50</state> <state>MAX_APDU=50</state>
<state>BIG_ENDIAN=0</state>
<state>MAX_TSM_TRANSACTIONS=0</state> <state>MAX_TSM_TRANSACTIONS=0</state>
<state>BACAPP_REAL</state> <state>BACAPP_REAL</state>
<state>BACAPP_UNSIGNED</state> <state>BACAPP_UNSIGNED</state>
+24 -25
View File
@@ -1,9 +1,9 @@
This port was done with the Atmel ATmega168 using two tools: This port was done with the Atmel ATmega168 using two tools:
1. The WinAVR compiler avr-gcc (GCC) 4.1.2 (WinAVR 20070525) 1. The WinAVR compiler avr-gcc (GCC) 4.1.2 (WinAVR 20070525)
and tools from <http://winavr.sourceforge.net/>, hints and and tools from <http://winavr.sourceforge.net/>, hints and
sample code from <http://www.avrfreaks.net/> and sample code from <http://www.avrfreaks.net/> and
<http://savannah.gnu.org/projects/avr-libc/>. <http://savannah.gnu.org/projects/avr-libc/>.
"avr-binutils, avr-gcc, and avr-libc form the heart of the "avr-binutils, avr-gcc, and avr-libc form the heart of the
Free Software toolchain for the Atmel AVR microcontrollers." Free Software toolchain for the Atmel AVR microcontrollers."
2. AVR Studio from Atmel <http://atmel.com/> 2. AVR Studio from Atmel <http://atmel.com/>
@@ -29,16 +29,16 @@ server. dlmstp is the datalink layer for MS/TP over RS-485.
I used the makefile from the command line on Windows: I used the makefile from the command line on Windows:
C:\code\bacnet-stack\ports\atmega168> make clean all C:\code\bacnet-stack\ports\atmega168> make clean all
CStack check for GCC is included in the device object as property 512. CStack check for GCC is included in the device object as property 512.
The compile shows 648 bytes of RAM used, and the ATmega168 has 1024 bytes The compile shows 648 bytes of RAM used, and the ATmega168 has 1024 bytes
of RAM, leaving 376 for the CStack. Property 512 index 0 returns 376 from of RAM, leaving 376 for the CStack. Property 512 index 0 returns 376 from
a ReadProperty request. My understanding is that the remaining unallocated a ReadProperty request. My understanding is that the remaining unallocated
RAM is used for the CStack. Keep this in mind when developing. RAM is used for the CStack. Keep this in mind when developing.
After some ReadProperty and WriteProperty requests, the CStack shows After some ReadProperty and WriteProperty requests, the CStack shows
159 CStack bytes free, meaning that 216 bytes of CStack are used. 159 CStack bytes free, meaning that 216 bytes of CStack are used.
Note that the value 0xC5 (197) was used to paint the CStack. Note that the value 0xC5 (197) was used to paint the CStack.
I also used the bacnet.aps project file in AVR Studio to I also used the bacnet.aps project file in AVR Studio to
make the project and simulate it, but have not kept it updated (FIXME). make the project and simulate it, but have not kept it updated (FIXME).
Compiler settings for IAR Embedded Workbench (FIXME: makefile?): Compiler settings for IAR Embedded Workbench (FIXME: makefile?):
@@ -95,14 +95,13 @@ List
Output assembler file (enabled) Output assembler file (enabled)
Preprocessor Preprocessor
Ignore standard include paths (not enabled) Ignore standard include paths (not enabled)
Include paths: Include paths:
$PROJ_DIR$ $PROJ_DIR$
$PROJ_DIR$\..\..\include $PROJ_DIR$\..\..\include
Preinclude file: (none) Preinclude file: (none)
Defined symbols: Defined symbols:
BACDL_MSTP BACDL_MSTP
MAX_APDU=50 MAX_APDU=50
BIG_ENDIAN=0
MAX_TSM_TRANSACTIONS=0 MAX_TSM_TRANSACTIONS=0
BACAPP_REAL BACAPP_REAL
BACAPP_UNSIGNED BACAPP_UNSIGNED
@@ -110,34 +109,34 @@ Preprocessor
BACAPP_CHARACTER_STRING BACAPP_CHARACTER_STRING
BACAPP_OBJECT_ID BACAPP_OBJECT_ID
WRITE_PROPERTY WRITE_PROPERTY
Diagnostics Diagnostics
(not enabled) (not enabled)
MISRA C MISRA C
(not enabled) (not enabled)
Extra Options Extra Options
Use command line options (not enabled) Use command line options (not enabled)
Note: The BACnet Stack at Sourceforge source code has to be built Note: The BACnet Stack at Sourceforge source code has to be built
with lots of different compilers. The IAR compiler has particularly with lots of different compilers. The IAR compiler has particularly
strong (pedantic) source checking and generates several warnings when strong (pedantic) source checking and generates several warnings when
compiling the source code. Unfortunately not all warnings can be compiling the source code. Unfortunately not all warnings can be
fixed by modifying the source code. Some warnings have therefore been fixed by modifying the source code. Some warnings have therefore been
disabled in the project file. disabled in the project file.
Compiler Diagnostics: Compiler Diagnostics:
(Pe550) I initilize all local variables as a best practice. (Pe550) I initilize all local variables as a best practice.
Linker Diagnostics: Linker Diagnostics:
(w31) The supplied standard libraries expect char parameters to (w31) The supplied standard libraries expect char parameters to
be unsigned (in functions such as strncpy(), etc.). It may be unsigned (in functions such as strncpy(), etc.). It may
be possible to recompile the libraries with signed plain char's. be possible to recompile the libraries with signed plain char's.
The BACnet Capabilities include WhoIs, I-Am, ReadProperty, and The BACnet Capabilities include WhoIs, I-Am, ReadProperty, and
WriteProperty support. The BACnet objects include a Device object, WriteProperty support. The BACnet objects include a Device object,
10 Binary Value objects, and 10 Analog Value objects. An LED is 10 Binary Value objects, and 10 Analog Value objects. An LED is
controlled by Binary Value object instance 0. All required object controlled by Binary Value object instance 0. All required object
properties can be retrieved using ReadProperty. The Present_Value properties can be retrieved using ReadProperty. The Present_Value
property of the Analog Value and Binary Value objects can be property of the Analog Value and Binary Value objects can be
written using WriteProperty. The Object_Identifier, Object_Name, written using WriteProperty. The Object_Identifier, Object_Name,
Max_Info_Frames, Max_Master, and baud rate (property 9600) of the Max_Info_Frames, Max_Master, and baud rate (property 9600) of the
Device object can be written using WriteProperty. Device object can be written using WriteProperty.
With full optimization, the statistics on the demo are: With full optimization, the statistics on the demo are:
-2
View File
@@ -56,7 +56,6 @@
<ListValues> <ListValues>
<Value>BACDL_MSTP</Value> <Value>BACDL_MSTP</Value>
<Value>MAX_APDU=128</Value> <Value>MAX_APDU=128</Value>
<Value>BIG_ENDIAN=0</Value>
<Value>MAX_TSM_TRANSACTIONS=0</Value> <Value>MAX_TSM_TRANSACTIONS=0</Value>
<Value>MSTP_PDU_PACKET_COUNT=2</Value> <Value>MSTP_PDU_PACKET_COUNT=2</Value>
<Value>MAX_CHARACTER_STRING_BYTES=64</Value> <Value>MAX_CHARACTER_STRING_BYTES=64</Value>
@@ -108,7 +107,6 @@
<ListValues> <ListValues>
<Value>BACDL_MSTP</Value> <Value>BACDL_MSTP</Value>
<Value>MAX_APDU=128</Value> <Value>MAX_APDU=128</Value>
<Value>BIG_ENDIAN=0</Value>
<Value>MAX_TSM_TRANSACTIONS=0</Value> <Value>MAX_TSM_TRANSACTIONS=0</Value>
<Value>MSTP_PDU_PACKET_COUNT=2</Value> <Value>MSTP_PDU_PACKET_COUNT=2</Value>
<Value>MAX_CHARACTER_STRING_BYTES=64</Value> <Value>MAX_CHARACTER_STRING_BYTES=64</Value>
-2
View File
@@ -257,7 +257,6 @@
<state>BACDL_MSTP</state> <state>BACDL_MSTP</state>
<state>MAX_ANALOG_INPUTS=100</state> <state>MAX_ANALOG_INPUTS=100</state>
<state>MAX_APDU=50</state> <state>MAX_APDU=50</state>
<state>BIG_ENDIAN=0</state>
<state>MAX_TSM_TRANSACTIONS=0</state> <state>MAX_TSM_TRANSACTIONS=0</state>
<state>MSTP_PDU_PACKET_COUNT=2</state> <state>MSTP_PDU_PACKET_COUNT=2</state>
<state>MAX_CHARACTER_STRING_BYTES=64</state> <state>MAX_CHARACTER_STRING_BYTES=64</state>
@@ -1323,7 +1322,6 @@
<state>NDEBUG</state> <state>NDEBUG</state>
<state>BACDL_MSTP</state> <state>BACDL_MSTP</state>
<state>MAX_APDU=128</state> <state>MAX_APDU=128</state>
<state>BIG_ENDIAN=0</state>
<state>MAX_TSM_TRANSACTIONS=0</state> <state>MAX_TSM_TRANSACTIONS=0</state>
<state>MSTP_PDU_PACKET_COUNT=2</state> <state>MSTP_PDU_PACKET_COUNT=2</state>
<state>MAX_CHARACTER_STRING_BYTES=64</state> <state>MAX_CHARACTER_STRING_BYTES=64</state>
+1 -1
View File
@@ -1,7 +1,7 @@
<!DOCTYPE CrossStudio_Project_File> <!DOCTYPE CrossStudio_Project_File>
<solution Name="bacnet" version="2"> <solution Name="bacnet" version="2">
<project Name="bacnet"> <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"> <folder Name="Source Files">
<configuration Name="Common" filter="c;h;s;asm;inc;s90"/> <configuration Name="Common" filter="c;h;s;asm;inc;s90"/>
<file file_name="adc.c"> <file file_name="adc.c">
+42
View File
@@ -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"/> value="..\;..\..\..\include;..\..\..\demo\object"/>
<property key="optimization-master" value="Enable all"/> <property key="optimization-master" value="Enable all"/>
<property key="preprocessor-macros" <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="procedural-abstraction-passes" value="0"/>
<property key="storage-class" value="sca"/> <property key="storage-class" value="sca"/>
<property key="verbose" value="false"/> <property key="verbose" value="false"/>
+1 -1
View File
@@ -269,7 +269,7 @@ suite_state=
[TOOL_SETTINGS] [TOOL_SETTINGS]
TS{DD2213A8-6310-47B1-8376-9430CDFC013F}= TS{DD2213A8-6310-47B1-8376-9430CDFC013F}=
TS{BFD27FBA-4A02-4C0E-A5E5-B812F3E7707C}=/m"$(BINDIR_)$(TARGETBASE).map" /o"$(TARGETBASE).cof" 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}= TS{ADE93A55-C7C7-4D4D-A4BA-59305F7D0391}=
[INSTRUMENTED_TRACE] [INSTRUMENTED_TRACE]
enable=0 enable=0
+2 -3
View File
@@ -1,12 +1,12 @@
BACnet Stack - SourceForge.net BACnet Stack - SourceForge.net
Build for MPLAB IDE Build for MPLAB IDE
These are some settings that are important when building These are some settings that are important when building
the BACnet Stack using MPLAB IDE and MCC18 Compiler, the BACnet Stack using MPLAB IDE and MCC18 Compiler,
1. Add the files to the project that you need: 1. Add the files to the project that you need:
abort.c, apdu.c, bacapp.c, bacdcode.c, bacerror.c, abort.c, apdu.c, bacapp.c, bacdcode.c, bacerror.c,
bacstr.c, crc.c, datetime.c, dcc.c, iam.c, bacstr.c, crc.c, datetime.c, dcc.c, iam.c,
npdu.c, rd.c, reject.c, rp.c, whois.c, wp.c npdu.c, rd.c, reject.c, rp.c, whois.c, wp.c
From ports/picxx: isr.c, main.c, rs485.c, mstp.c, dlmstp.c From ports/picxx: isr.c, main.c, rs485.c, mstp.c, dlmstp.c
@@ -31,7 +31,6 @@ MPLAB C18 Tab: General: Macro Definitions:
PRINT_ENABLED=0 PRINT_ENABLED=0
BACDL_MSTP=1 BACDL_MSTP=1
TSM_ENABLED=0 TSM_ENABLED=0
BIG_ENDIAN=0
3. The linker script must reserve some extra stack space. 3. The linker script must reserve some extra stack space.
@@ -135,7 +135,7 @@
value="..\;..\..\..\include;..\..\..\demo\object"/> value="..\;..\..\..\include;..\..\..\demo\object"/>
<property key="optimization-master" value="Enable all"/> <property key="optimization-master" value="Enable all"/>
<property key="preprocessor-macros" <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="procedural-abstraction-passes" value="0"/>
<property key="storage-class" value="sca"/> <property key="storage-class" value="sca"/>
<property key="verbose" value="false"/> <property key="verbose" value="false"/>
+2 -3
View File
@@ -1,12 +1,12 @@
BACnet Stack - SourceForge.net BACnet Stack - SourceForge.net
Build for MPLAB IDE Build for MPLAB IDE
These are some settings that are important when building These are some settings that are important when building
the BACnet Stack using MPLAB IDE and MCC18 Compiler, the BACnet Stack using MPLAB IDE and MCC18 Compiler,
1. Add the files to the project that you need: 1. Add the files to the project that you need:
abort.c, apdu.c, bacapp.c, bacdcode.c, bacerror.c, abort.c, apdu.c, bacapp.c, bacdcode.c, bacerror.c,
bacstr.c, crc.c, datetime.c, dcc.c, iam.c, bacstr.c, crc.c, datetime.c, dcc.c, iam.c,
npdu.c, rd.c, reject.c, rp.c, whois.c, wp.c npdu.c, rd.c, reject.c, rp.c, whois.c, wp.c
From ports/picxx: isr.c, main.c, rs485.c, mstp.c, dlmstp.c From ports/picxx: isr.c, main.c, rs485.c, mstp.c, dlmstp.c
@@ -31,7 +31,6 @@ MPLAB C18 Tab: General: Macro Definitions:
PRINT_ENABLED=0 PRINT_ENABLED=0
BACDL_MSTP=1 BACDL_MSTP=1
TSM_ENABLED=0 TSM_ENABLED=0
BIG_ENDIAN=0
3. The linker script must reserve some extra stack space. 3. The linker script must reserve some extra stack space.
-1
View File
@@ -228,7 +228,6 @@
<state>USE_STDPERIPH_DRIVER</state> <state>USE_STDPERIPH_DRIVER</state>
<state>BACDL_MSTP</state> <state>BACDL_MSTP</state>
<state>MAX_APDU=480</state> <state>MAX_APDU=480</state>
<state>BIG_ENDIAN=0</state>
<state>MAX_TSM_TRANSACTIONS=0</state> <state>MAX_TSM_TRANSACTIONS=0</state>
<state>BACAPP_BOOLEAN</state> <state>BACAPP_BOOLEAN</state>
<state>BACAPP_REAL</state> <state>BACAPP_REAL</state>
+28
View File
@@ -2023,6 +2023,20 @@ int encode_context_real(uint8_t *apdu, uint8_t tag_number, float value)
return len; 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 #if BACNET_USE_DOUBLE
/* from clause 20.2.7 Encoding of a Double Precision Real Number Value */ /* from clause 20.2.7 Encoding of a Double Precision Real Number Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */ /* 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; 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 #endif
/* from clause 20.2.13 Encoding of a Time Value */ /* from clause 20.2.13 Encoding of a Time Value */
+10
View File
@@ -182,6 +182,11 @@ extern "C" {
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
float value); 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 */ /* from clause 20.2.7 Encoding of a Double Precision Real Number Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */ /* and 20.2.1 General Rules for Encoding BACnet Tags */
@@ -196,6 +201,11 @@ extern "C" {
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
double value); 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 */ /* from clause 20.2.14 Encoding of an Object Identifier Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */ /* and 20.2.1 General Rules for Encoding BACnet Tags */
+63 -153
View File
@@ -41,13 +41,10 @@
#include "bacnet/bacstr.h" #include "bacnet/bacstr.h"
#include "bacnet/bacint.h" #include "bacnet/bacint.h"
#include "bacnet/bacreal.h" #include "bacnet/bacreal.h"
#include "bacnet/basic/sys/bigend.h"
/** @file bacreal.c Encode/Decode Floating Point (Real) Types */ #ifndef BACNET_USE_DOUBLE
#define BACNET_USE_DOUBLE 1
/* 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
#endif #endif
/* from clause 20.2.6 Encoding of a Real Number Value */ /* 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; } my_data;
/* NOTE: assumes the compiler stores float as IEEE-754 float */ /* 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[0] = apdu[0];
my_data.byte[1] = apdu[1]; my_data.byte[1] = apdu[1];
my_data.byte[2] = apdu[2]; my_data.byte[2] = apdu[2];
my_data.byte[3] = apdu[3]; my_data.byte[3] = apdu[3];
#else } else {
my_data.byte[0] = apdu[3]; my_data.byte[0] = apdu[3];
my_data.byte[1] = apdu[2]; my_data.byte[1] = apdu[2];
my_data.byte[2] = apdu[1]; my_data.byte[2] = apdu[1];
my_data.byte[3] = apdu[0]; my_data.byte[3] = apdu[0];
#endif }
*real_value = my_data.real_value; *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 */ /* from clause 20.2.6 Encoding of a Real Number Value */
/* returns the number of apdu bytes consumed */ /* returns the number of apdu bytes consumed */
int encode_bacnet_real(float value, uint8_t *apdu) 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 */ /* NOTE: assumes the compiler stores float as IEEE-754 float */
my_data.real_value = value; my_data.real_value = value;
#if BIG_ENDIAN if (big_endian()) {
apdu[0] = my_data.byte[0]; apdu[0] = my_data.byte[0];
apdu[1] = my_data.byte[1]; apdu[1] = my_data.byte[1];
apdu[2] = my_data.byte[2]; apdu[2] = my_data.byte[2];
apdu[3] = my_data.byte[3]; apdu[3] = my_data.byte[3];
#else } else {
apdu[0] = my_data.byte[3]; apdu[0] = my_data.byte[3];
apdu[1] = my_data.byte[2]; apdu[1] = my_data.byte[2];
apdu[2] = my_data.byte[1]; apdu[2] = my_data.byte[1];
apdu[3] = my_data.byte[0]; apdu[3] = my_data.byte[0];
#endif }
return 4; return 4;
} }
@@ -139,26 +122,25 @@ int decode_double(uint8_t *apdu, double *double_value)
} my_data; } my_data;
/* NOTE: assumes the compiler stores float as IEEE-754 float */ /* 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[0] = apdu[0];
my_data.byte[1] = apdu[1]; my_data.byte[1] = apdu[1];
my_data.byte[2] = apdu[2]; my_data.byte[2] = apdu[2];
my_data.byte[3] = apdu[3]; my_data.byte[3] = apdu[3];
my_data.byte[4] = apdu[4]; my_data.byte[4] = apdu[4];
my_data.byte[5] = apdu[5]; my_data.byte[5] = apdu[5];
my_data.byte[6] = apdu[6]; my_data.byte[6] = apdu[6];
my_data.byte[7] = apdu[7]; my_data.byte[7] = apdu[7];
#else } else {
my_data.byte[0] = apdu[7]; my_data.byte[0] = apdu[7];
my_data.byte[1] = apdu[6]; my_data.byte[1] = apdu[6];
my_data.byte[2] = apdu[5]; my_data.byte[2] = apdu[5];
my_data.byte[3] = apdu[4]; my_data.byte[3] = apdu[4];
my_data.byte[4] = apdu[3]; my_data.byte[4] = apdu[3];
my_data.byte[5] = apdu[2]; my_data.byte[5] = apdu[2];
my_data.byte[6] = apdu[1]; my_data.byte[6] = apdu[1];
my_data.byte[7] = apdu[0]; my_data.byte[7] = apdu[0];
#endif }
*double_value = my_data.double_value; *double_value = my_data.double_value;
return 8; return 8;
@@ -185,98 +167,26 @@ int encode_bacnet_double(double value, uint8_t *apdu)
/* NOTE: assumes the compiler stores float as IEEE-754 float */ /* NOTE: assumes the compiler stores float as IEEE-754 float */
my_data.double_value = value; my_data.double_value = value;
#if BIG_ENDIAN if (big_endian()) {
apdu[0] = my_data.byte[0]; apdu[0] = my_data.byte[0];
apdu[1] = my_data.byte[1]; apdu[1] = my_data.byte[1];
apdu[2] = my_data.byte[2]; apdu[2] = my_data.byte[2];
apdu[3] = my_data.byte[3]; apdu[3] = my_data.byte[3];
apdu[4] = my_data.byte[4]; apdu[4] = my_data.byte[4];
apdu[5] = my_data.byte[5]; apdu[5] = my_data.byte[5];
apdu[6] = my_data.byte[6]; apdu[6] = my_data.byte[6];
apdu[7] = my_data.byte[7]; apdu[7] = my_data.byte[7];
#else } else {
apdu[0] = my_data.byte[7]; apdu[0] = my_data.byte[7];
apdu[1] = my_data.byte[6]; apdu[1] = my_data.byte[6];
apdu[2] = my_data.byte[5]; apdu[2] = my_data.byte[5];
apdu[3] = my_data.byte[4]; apdu[3] = my_data.byte[4];
apdu[4] = my_data.byte[3]; apdu[4] = my_data.byte[3];
apdu[5] = my_data.byte[2]; apdu[5] = my_data.byte[2];
apdu[6] = my_data.byte[1]; apdu[6] = my_data.byte[1];
apdu[7] = my_data.byte[0]; apdu[7] = my_data.byte[0];
#endif }
return 8; 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 #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 */
-21
View File
@@ -45,11 +45,6 @@ extern "C" {
float *real_value); float *real_value);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
int decode_context_real(
uint8_t * apdu,
uint8_t tag_number,
float *real_value);
BACNET_STACK_EXPORT
int encode_bacnet_real( int encode_bacnet_real(
float value, float value,
uint8_t * apdu); uint8_t * apdu);
@@ -58,11 +53,6 @@ extern "C" {
uint8_t * apdu, uint8_t * apdu,
double *real_value); double *real_value);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
int decode_context_double(
uint8_t * apdu,
uint8_t tag_number,
double *double_value);
BACNET_STACK_EXPORT
int decode_double_safe( int decode_double_safe(
uint8_t * apdu, uint8_t * apdu,
uint32_t len_value, uint32_t len_value,
@@ -73,17 +63,6 @@ extern "C" {
double value, double value,
uint8_t * apdu); 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 #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
+3 -1
View File
@@ -3,8 +3,9 @@
/** @file bigend.c Determination of Endianess */ /** @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. */ /* Big-Endian systems save the most significant byte first. */
/* Sun and Motorola processors, IBM-370s and PDP-10s are big-endian. */ /* Sun and Motorola processors, IBM-370s and PDP-10s are big-endian. */
/* "Network Byte Order" is also know as "Big-Endian Byte Order" */ /* "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); return (u.c[sizeof(long) - 1] == 1);
} }
#endif
+14 -16
View File
@@ -29,26 +29,24 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #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. */ #ifdef BACNET_BIG_ENDIAN
/* Sun and Motorola processors, IBM-370s and PDP-10s are big-endian. */ #define big_endian() BACNET_BIG_ENDIAN
/* for example, a 4 byte integer 67305985 is 0x04030201 in hexidecimal. */ #else
/* 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 */
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
int big_endian( int big_endian(
void); void);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
-8
View File
@@ -68,14 +68,6 @@
#endif #endif
#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 */ /* Define your Vendor Identifier assigned by ASHRAE */
#if !defined(BACNET_VENDOR_ID) #if !defined(BACNET_VENDOR_ID)
#define BACNET_VENDOR_ID 260 #define BACNET_VENDOR_ID 260
+5
View File
@@ -61,6 +61,11 @@ bacint: logfile bacint.mak
( ./bacint >> ${LOGFILE} ) ( ./bacint >> ${LOGFILE} )
$(MAKE) -s -f bacint.mak clean $(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 bacstr: logfile bacstr.mak
$(MAKE) -s -f bacstr.mak clean all $(MAKE) -s -f bacstr.mak clean all
( ./bacstr >> ${LOGFILE} ) ( ./bacstr >> ${LOGFILE} )
+43
View File
@@ -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
+98
View File
@@ -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;
}