diff --git a/.gitignore b/.gitignore index 73105a10..b1329144 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*.log *.a *.o *.exe @@ -63,4 +64,4 @@ address_cache /build/* /_build/* CMakeLists.txt.user -/out/* \ No newline at end of file +/out/* diff --git a/doc/README.faq b/doc/README.faq index 61790105..5e5d92b7 100644 --- a/doc/README.faq +++ b/doc/README.faq @@ -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...)? diff --git a/doc/README.msvc b/doc/README.msvc index 6d33f3bb..15494eea 100644 --- a/doc/README.msvc +++ b/doc/README.msvc @@ -1,7 +1,7 @@ BACnet Stack - SourceForge.net 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. 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 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 @@ -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 TSM_ENABLED=1 - enables the Transaction State Machine for clients 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 2. Select "Settings..." 3. Select the "C/C++" tab (3rd Tab) 4. Select the Category: General 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. 7. Press OK 8. Compile the entire project again... @@ -39,8 +38,8 @@ unix2dos bacnet.dsp Q. error LNK2001: unresolved external symbol _WinMain@16 -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, +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, you will have to add all the Windows GUI code, including WinMain(). I recommend that you use a framework, such as WxWidgets/WxWindows, 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 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 2. Select "Settings..." 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 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 2. Select "Settings..." 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 A. The BACnet stack uses a preprocessor define to configure -client functionality in the Transaction State Machine (TSM). -In Visual C++, add a Preprocessor Definition by: +client functionality in the Transaction State Machine (TSM). +In Visual C++, add a Preprocessor Definition by: 1. Select "Project" menu 2. Select "Settings..." 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 5. Select the Multithreaded from the "Use runtime library" box options -Q. error LNK2019: Verweis auf nicht aufgelöstes externes Symbol - "_GetAdaptersInfo@8" in Funktion "_getIpMaskForIpAddress". -A. There is the Iphlpapi.lib library missing from the VC++ project - (for the GetAdaptersInfo error) that you need to add: +Q. error LNK2019: Verweis auf nicht aufgelöstes externes Symbol + "_GetAdaptersInfo@8" in Funktion "_getIpMaskForIpAddress". +A. There is the Iphlpapi.lib library missing from the VC++ project + (for the GetAdaptersInfo error) that you need to add: http://msdn2.microsoft.com/en-us/library/aa916102.aspx Note that Iphlpapi.lib/.h is not included with Visual C++ 6.0; you would need to download the platform SDK to get it. diff --git a/ports/atmega168/bacnet.ewp b/ports/atmega168/bacnet.ewp index 2517d36f..fbcc6cda 100644 --- a/ports/atmega168/bacnet.ewp +++ b/ports/atmega168/bacnet.ewp @@ -256,7 +256,6 @@ CCDefines BACDL_MSTP=1 MAX_APDU=50 - BIG_ENDIAN=0 MAX_TSM_TRANSACTIONS=0 BACAPP_REAL BACAPP_UNSIGNED @@ -1318,7 +1317,6 @@ NDEBUG BACDL_MSTP MAX_APDU=50 - BIG_ENDIAN=0 MAX_TSM_TRANSACTIONS=0 BACAPP_REAL BACAPP_UNSIGNED diff --git a/ports/atmega168/readme.txt b/ports/atmega168/readme.txt index 2e0084a3..6db79e9e 100644 --- a/ports/atmega168/readme.txt +++ b/ports/atmega168/readme.txt @@ -1,9 +1,9 @@ This port was done with the Atmel ATmega168 using two tools: 1. The WinAVR compiler avr-gcc (GCC) 4.1.2 (WinAVR 20070525) -and tools from , hints and -sample code from and +and tools from , hints and +sample code from and . -"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." 2. AVR Studio from Atmel @@ -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: 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 of RAM, leaving 376 for the CStack. Property 512 index 0 returns 376 from a ReadProperty request. My understanding is that the remaining unallocated -RAM is used for the CStack. Keep this in mind when developing. -After some ReadProperty and WriteProperty requests, the CStack shows -159 CStack bytes free, meaning that 216 bytes of CStack are used. -Note that the value 0xC5 (197) was used to paint the CStack. +RAM is used for the CStack. Keep this in mind when developing. +After some ReadProperty and WriteProperty requests, the CStack shows +159 CStack bytes free, meaning that 216 bytes of CStack are used. +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). Compiler settings for IAR Embedded Workbench (FIXME: makefile?): @@ -95,14 +95,13 @@ List Output assembler file (enabled) Preprocessor Ignore standard include paths (not enabled) - Include paths: + Include paths: $PROJ_DIR$ $PROJ_DIR$\..\..\include Preinclude file: (none) - Defined symbols: + Defined symbols: BACDL_MSTP MAX_APDU=50 - BIG_ENDIAN=0 MAX_TSM_TRANSACTIONS=0 BACAPP_REAL BACAPP_UNSIGNED @@ -110,34 +109,34 @@ Preprocessor BACAPP_CHARACTER_STRING BACAPP_OBJECT_ID WRITE_PROPERTY -Diagnostics +Diagnostics (not enabled) MISRA C (not enabled) Extra Options Use command line options (not enabled) -Note: The BACnet Stack at Sourceforge source code has to be built -with lots of different compilers. The IAR compiler has particularly -strong (pedantic) source checking and generates several warnings when -compiling the source code. Unfortunately not all warnings can be -fixed by modifying the source code. Some warnings have therefore been +Note: The BACnet Stack at Sourceforge source code has to be built +with lots of different compilers. The IAR compiler has particularly +strong (pedantic) source checking and generates several warnings when +compiling the source code. Unfortunately not all warnings can be +fixed by modifying the source code. Some warnings have therefore been disabled in the project file. Compiler Diagnostics: (Pe550) I initilize all local variables as a best practice. Linker Diagnostics: - (w31) The supplied standard libraries expect char parameters to - be unsigned (in functions such as strncpy(), etc.). It may + (w31) The supplied standard libraries expect char parameters to + be unsigned (in functions such as strncpy(), etc.). It may 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, -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 properties can be retrieved using ReadProperty. The Present_Value -property of the Analog Value and Binary Value objects can be -written using WriteProperty. The Object_Identifier, Object_Name, -Max_Info_Frames, Max_Master, and baud rate (property 9600) of the +property of the Analog Value and Binary Value objects can be +written using WriteProperty. The Object_Identifier, Object_Name, +Max_Info_Frames, Max_Master, and baud rate (property 9600) of the Device object can be written using WriteProperty. With full optimization, the statistics on the demo are: diff --git a/ports/bdk-atxx4-mstp/bacnet.cproj b/ports/bdk-atxx4-mstp/bacnet.cproj index 99e48e43..cc739311 100644 --- a/ports/bdk-atxx4-mstp/bacnet.cproj +++ b/ports/bdk-atxx4-mstp/bacnet.cproj @@ -56,7 +56,6 @@ BACDL_MSTP MAX_APDU=128 - BIG_ENDIAN=0 MAX_TSM_TRANSACTIONS=0 MSTP_PDU_PACKET_COUNT=2 MAX_CHARACTER_STRING_BYTES=64 @@ -108,7 +107,6 @@ BACDL_MSTP MAX_APDU=128 - BIG_ENDIAN=0 MAX_TSM_TRANSACTIONS=0 MSTP_PDU_PACKET_COUNT=2 MAX_CHARACTER_STRING_BYTES=64 diff --git a/ports/bdk-atxx4-mstp/bacnet.ewp b/ports/bdk-atxx4-mstp/bacnet.ewp index 394090e4..8bf3e79a 100644 --- a/ports/bdk-atxx4-mstp/bacnet.ewp +++ b/ports/bdk-atxx4-mstp/bacnet.ewp @@ -257,7 +257,6 @@ BACDL_MSTP MAX_ANALOG_INPUTS=100 MAX_APDU=50 - BIG_ENDIAN=0 MAX_TSM_TRANSACTIONS=0 MSTP_PDU_PACKET_COUNT=2 MAX_CHARACTER_STRING_BYTES=64 @@ -1323,7 +1322,6 @@ NDEBUG BACDL_MSTP MAX_APDU=128 - BIG_ENDIAN=0 MAX_TSM_TRANSACTIONS=0 MSTP_PDU_PACKET_COUNT=2 MAX_CHARACTER_STRING_BYTES=64 diff --git a/ports/bdk-atxx4-mstp/bacnet.hzp b/ports/bdk-atxx4-mstp/bacnet.hzp index 0d8cc710..64dfbf9d 100644 --- a/ports/bdk-atxx4-mstp/bacnet.hzp +++ b/ports/bdk-atxx4-mstp/bacnet.hzp @@ -1,7 +1,7 @@ - + diff --git a/ports/bdk-atxx4-mstp/bacnet.hzs b/ports/bdk-atxx4-mstp/bacnet.hzs new file mode 100644 index 00000000..1beed8b5 --- /dev/null +++ b/ports/bdk-atxx4-mstp/bacnet.hzs @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ports/pic18f6720/BACnet-Server.X/nbproject/configurations.xml b/ports/pic18f6720/BACnet-Server.X/nbproject/configurations.xml index 9f900ef6..3c186e58 100644 --- a/ports/pic18f6720/BACnet-Server.X/nbproject/configurations.xml +++ b/ports/pic18f6720/BACnet-Server.X/nbproject/configurations.xml @@ -135,7 +135,7 @@ value="..\;..\..\..\include;..\..\..\demo\object"/> + value="PRINT_ENABLED=0;BACDL_MSTP=1;MAX_APDU=50;MAX_TSM_TRANSACTIONS=0;BACAPP_MINIMAL"/> diff --git a/ports/pic18f6720/BACnet-Server.mcp b/ports/pic18f6720/BACnet-Server.mcp index 2b4a169e..f3ff4c4a 100644 --- a/ports/pic18f6720/BACnet-Server.mcp +++ b/ports/pic18f6720/BACnet-Server.mcp @@ -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 diff --git a/ports/pic18f6720/readme.txt b/ports/pic18f6720/readme.txt index c5095c69..889c3c19 100644 --- a/ports/pic18f6720/readme.txt +++ b/ports/pic18f6720/readme.txt @@ -1,12 +1,12 @@ BACnet Stack - SourceForge.net 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, 1. Add the files to the project that you need: 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 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 BACDL_MSTP=1 TSM_ENABLED=0 -BIG_ENDIAN=0 3. The linker script must reserve some extra stack space. diff --git a/ports/pic18f97j60/BACnet-Server.X/nbproject/configurations.xml b/ports/pic18f97j60/BACnet-Server.X/nbproject/configurations.xml index a3dbe89c..aadc5fad 100644 --- a/ports/pic18f97j60/BACnet-Server.X/nbproject/configurations.xml +++ b/ports/pic18f97j60/BACnet-Server.X/nbproject/configurations.xml @@ -135,7 +135,7 @@ value="..\;..\..\..\include;..\..\..\demo\object"/> + value="PRINT_ENABLED=0;BACDL_MSTP=1;MAX_APDU=50;MAX_TSM_TRANSACTIONS=0;BACAPP_MINIMAL"/> diff --git a/ports/pic18f97j60/readme.txt b/ports/pic18f97j60/readme.txt index c5095c69..889c3c19 100644 --- a/ports/pic18f97j60/readme.txt +++ b/ports/pic18f97j60/readme.txt @@ -1,12 +1,12 @@ BACnet Stack - SourceForge.net 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, 1. Add the files to the project that you need: 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 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 BACDL_MSTP=1 TSM_ENABLED=0 -BIG_ENDIAN=0 3. The linker script must reserve some extra stack space. diff --git a/ports/stm32f10x/bacnet.ewp b/ports/stm32f10x/bacnet.ewp index eb684b8b..5ddc79cd 100644 --- a/ports/stm32f10x/bacnet.ewp +++ b/ports/stm32f10x/bacnet.ewp @@ -228,7 +228,6 @@ USE_STDPERIPH_DRIVER BACDL_MSTP MAX_APDU=480 - BIG_ENDIAN=0 MAX_TSM_TRANSACTIONS=0 BACAPP_BOOLEAN BACAPP_REAL diff --git a/src/bacnet/bacdcode.c b/src/bacnet/bacdcode.c index 6fd7b55a..e8646f79 100644 --- a/src/bacnet/bacdcode.c +++ b/src/bacnet/bacdcode.c @@ -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 */ diff --git a/src/bacnet/bacdcode.h b/src/bacnet/bacdcode.h index 9b947347..0091f098 100644 --- a/src/bacnet/bacdcode.h +++ b/src/bacnet/bacdcode.h @@ -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 */ diff --git a/src/bacnet/bacreal.c b/src/bacnet/bacreal.c index 9a172a86..7515b406 100644 --- a/src/bacnet/bacreal.c +++ b/src/bacnet/bacreal.c @@ -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 - 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 - 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 + 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 { + my_data.byte[0] = apdu[3]; + my_data.byte[1] = apdu[2]; + my_data.byte[2] = apdu[1]; + my_data.byte[3] = apdu[0]; + } *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 - 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 - 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 + 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 { + apdu[0] = my_data.byte[3]; + apdu[1] = my_data.byte[2]; + apdu[2] = my_data.byte[1]; + apdu[3] = my_data.byte[0]; + } return 4; } @@ -139,26 +122,25 @@ int decode_double(uint8_t *apdu, double *double_value) } my_data; /* NOTE: assumes the compiler stores float as IEEE-754 float */ -#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]; - my_data.byte[4] = apdu[4]; - my_data.byte[5] = apdu[5]; - my_data.byte[6] = apdu[6]; - my_data.byte[7] = apdu[7]; -#else - my_data.byte[0] = apdu[7]; - my_data.byte[1] = apdu[6]; - my_data.byte[2] = apdu[5]; - my_data.byte[3] = apdu[4]; - my_data.byte[4] = apdu[3]; - my_data.byte[5] = apdu[2]; - my_data.byte[6] = apdu[1]; - my_data.byte[7] = apdu[0]; -#endif - + 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]; + my_data.byte[4] = apdu[4]; + my_data.byte[5] = apdu[5]; + my_data.byte[6] = apdu[6]; + my_data.byte[7] = apdu[7]; + } else { + my_data.byte[0] = apdu[7]; + my_data.byte[1] = apdu[6]; + my_data.byte[2] = apdu[5]; + my_data.byte[3] = apdu[4]; + my_data.byte[4] = apdu[3]; + my_data.byte[5] = apdu[2]; + my_data.byte[6] = apdu[1]; + my_data.byte[7] = apdu[0]; + } *double_value = my_data.double_value; 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 */ my_data.double_value = value; -#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]; - apdu[4] = my_data.byte[4]; - apdu[5] = my_data.byte[5]; - apdu[6] = my_data.byte[6]; - apdu[7] = my_data.byte[7]; -#else - apdu[0] = my_data.byte[7]; - apdu[1] = my_data.byte[6]; - apdu[2] = my_data.byte[5]; - apdu[3] = my_data.byte[4]; - apdu[4] = my_data.byte[3]; - apdu[5] = my_data.byte[2]; - apdu[6] = my_data.byte[1]; - apdu[7] = my_data.byte[0]; -#endif + 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]; + apdu[4] = my_data.byte[4]; + apdu[5] = my_data.byte[5]; + apdu[6] = my_data.byte[6]; + apdu[7] = my_data.byte[7]; + } else { + apdu[0] = my_data.byte[7]; + apdu[1] = my_data.byte[6]; + apdu[2] = my_data.byte[5]; + apdu[3] = my_data.byte[4]; + apdu[4] = my_data.byte[3]; + apdu[5] = my_data.byte[2]; + apdu[6] = my_data.byte[1]; + apdu[7] = my_data.byte[0]; + } 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 -#include -#include -#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 */ diff --git a/src/bacnet/bacreal.h b/src/bacnet/bacreal.h index 8af68d31..40414d03 100644 --- a/src/bacnet/bacreal.h +++ b/src/bacnet/bacreal.h @@ -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 */ diff --git a/src/bacnet/basic/sys/bigend.c b/src/bacnet/basic/sys/bigend.c index 2ccf6d07..84b680ee 100644 --- a/src/bacnet/basic/sys/bigend.c +++ b/src/bacnet/basic/sys/bigend.c @@ -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 diff --git a/src/bacnet/basic/sys/bigend.h b/src/bacnet/basic/sys/bigend.h index 8d9bfe35..09ac987c 100644 --- a/src/bacnet/basic/sys/bigend.h +++ b/src/bacnet/basic/sys/bigend.h @@ -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 } diff --git a/src/bacnet/config.h b/src/bacnet/config.h index 9a35015d..47d9c4bc 100644 --- a/src/bacnet/config.h +++ b/src/bacnet/config.h @@ -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 diff --git a/test/Makefile b/test/Makefile index 5c690ac6..374c2747 100644 --- a/test/Makefile +++ b/test/Makefile @@ -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} ) diff --git a/test/bacnet/bacreal/Makefile b/test/bacnet/bacreal/Makefile new file mode 100644 index 00000000..0bc0f52b --- /dev/null +++ b/test/bacnet/bacreal/Makefile @@ -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 diff --git a/test/bacnet/bacreal/main.c b/test/bacnet/bacreal/main.c new file mode 100644 index 00000000..757ff39e --- /dev/null +++ b/test/bacnet/bacreal/main.c @@ -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 +#include +#include +#include +#include +#include +#include +#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; +} +