From adf6b5f1fbaced26920a205ddb1cbdc33b8506b1 Mon Sep 17 00:00:00 2001 From: Steve Karg Date: Mon, 1 Apr 2024 13:58:37 -0500 Subject: [PATCH] Bugfix/zephyr defines kconfig (#610) * Added COV features to time-value object * Added zephyr config names with BACNET prefix --- ports/zephyr/bacnet-config.h | 22 ------ src/bacnet/basic/object/time_value.c | 100 +++++++++++++++++++++++++-- src/bacnet/basic/object/time_value.h | 12 ++++ zephyr/CMakeLists.txt | 39 ++++++++--- zephyr/Kconfig | 62 ++++++++++++++++- 5 files changed, 195 insertions(+), 40 deletions(-) diff --git a/ports/zephyr/bacnet-config.h b/ports/zephyr/bacnet-config.h index c3655457..e9a8ff9b 100644 --- a/ports/zephyr/bacnet-config.h +++ b/ports/zephyr/bacnet-config.h @@ -19,26 +19,4 @@ /* provides platform specific define for ARRAY_SIZE */ #include -/* some smaller defaults for microcontrollers */ -#if !defined(MAX_TSM_TRANSACTIONS) -#define MAX_TSM_TRANSACTIONS 1 -#endif -#if !defined(MAX_ADDRESS_CACHE) -#define MAX_ADDRESS_CACHE 1 -#endif -#if !defined(MAX_CHARACTER_STRING_BYTES) -#define MAX_CHARACTER_STRING_BYTES 64 -#endif -#if !defined(MAX_OCTET_STRING_BYTES) -#define MAX_OCTET_STRING_BYTES 64 -#endif - -/* K.6.6 BIBB - Network Management-BBMD Configuration-B (NM-BBMDC-B)*/ -#if !defined(MAX_BBMD_ENTRIES) -#define MAX_BBMD_ENTRIES 5 -#endif -#if !defined(MAX_FD_ENTRIES) -#define MAX_FD_ENTRIES 5 -#endif - #endif diff --git a/src/bacnet/basic/object/time_value.c b/src/bacnet/basic/object/time_value.c index c2da8f72..7445e89a 100644 --- a/src/bacnet/basic/object/time_value.c +++ b/src/bacnet/basic/object/time_value.c @@ -30,6 +30,7 @@ #include "bacnet/apdu.h" #include "bacnet/npdu.h" #include "bacnet/abort.h" +#include "bacnet/datetime.h" #include "bacnet/proplist.h" #include "bacnet/reject.h" #include "bacnet/rp.h" @@ -40,7 +41,7 @@ #include "time_value.h" struct object_data { - bool Changed : 1; + bool Change_Of_Value : 1; bool Write_Enabled : 1; bool Out_Of_Service : 1; BACNET_TIME Present_Value; @@ -173,7 +174,7 @@ bool Time_Value_Present_Value(uint32_t object_instance, BACNET_TIME *value) pObject = Keylist_Data(Object_List, object_instance); if (pObject) { if (pObject->Out_Of_Service) { - *value = pObject->Present_Value; + datetime_copy_time(value, &pObject->Present_Value); status = true; } else { status = datetime_local(&date, value, NULL, NULL); @@ -198,7 +199,10 @@ bool Time_Value_Present_Value_Set(uint32_t object_instance, BACNET_TIME *value) pObject = Keylist_Data(Object_List, object_instance); if (pObject) { - pObject->Present_Value = *value; + if (datetime_compare_time(&pObject->Present_Value, value) != 0) { + pObject->Change_Of_Value = true; + datetime_copy_time(&pObject->Present_Value, value); + } status = true; } @@ -230,8 +234,11 @@ static bool Time_Value_Present_Value_Write(uint32_t object_instance, if (pObject) { (void)priority; if (pObject->Write_Enabled) { - old_value = pObject->Present_Value; - pObject->Present_Value = *value; + datetime_copy_time(&old_value, &pObject->Present_Value); + if (datetime_compare_time(&pObject->Present_Value, value) != 0) { + pObject->Change_Of_Value = true; + datetime_copy_time(&pObject->Present_Value, value); + } if (Time_Value_Write_Present_Value_Callback) { Time_Value_Write_Present_Value_Callback( object_instance, &old_value, value); @@ -403,6 +410,85 @@ static bool BACnetARRAY_Property( BACnetARRAY_Properties, object_property); } + +bool Time_Value_Change_Of_Value(uint32_t object_instance) +{ + bool status = false; + struct object_data *pObject; + + pObject = Keylist_Data(Object_List, object_instance); + if (pObject) { + status = pObject->Change_Of_Value; + } + + return status; +} + +void Time_Value_Change_Of_Value_Clear(uint32_t object_instance) +{ + struct object_data *pObject; + + pObject = Keylist_Data(Object_List, object_instance); + if (pObject) { + pObject->Change_Of_Value = false; + } + + return; +} + +/** + * For a given object instance-number, loads the value_list with the COV data. + * + * @param object_instance - object-instance number of the object + * @param value_list - list of COV data + * + * @return true if the value list is encoded + */ +bool Time_Value_Encode_Value_List( + uint32_t object_instance, BACNET_PROPERTY_VALUE *value_list) +{ + bool status = false; + BACNET_TIME btime = { 0 }; + + if (value_list) { + value_list->propertyIdentifier = PROP_PRESENT_VALUE; + value_list->propertyArrayIndex = BACNET_ARRAY_ALL; + value_list->value.context_specific = false; + value_list->value.tag = BACNET_APPLICATION_TAG_ENUMERATED; + value_list->value.next = NULL; + Time_Value_Present_Value(object_instance, &btime); + datetime_copy_time(&value_list->value.type.Time, &btime); + value_list->priority = BACNET_NO_PRIORITY; + value_list = value_list->next; + } + if (value_list) { + value_list->propertyIdentifier = PROP_STATUS_FLAGS; + value_list->propertyArrayIndex = BACNET_ARRAY_ALL; + value_list->value.context_specific = false; + value_list->value.tag = BACNET_APPLICATION_TAG_BIT_STRING; + value_list->value.next = NULL; + bitstring_init(&value_list->value.type.Bit_String); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_IN_ALARM, false); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_FAULT, false); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_OVERRIDDEN, false); + if (Time_Value_Out_Of_Service(object_instance)) { + bitstring_set_bit(&value_list->value.type.Bit_String, + STATUS_FLAG_OUT_OF_SERVICE, true); + } else { + bitstring_set_bit(&value_list->value.type.Bit_String, + STATUS_FLAG_OUT_OF_SERVICE, false); + } + value_list->priority = BACNET_NO_PRIORITY; + value_list->next = NULL; + status = true; + } + + return status; +} + /** * ReadProperty handler for this object. For the given ReadProperty * data, the application_data is loaded or the error flags are set. @@ -654,8 +740,8 @@ uint32_t Time_Value_Create(uint32_t object_instance) } pObject->Object_Name = NULL; pObject->Description = NULL; - memset(&pObject->Present_Value, 0, sizeof(pObject->Present_Value)); - pObject->Changed = false; + datetime_set_time(&pObject->Present_Value, 0, 0, 0, 0); + pObject->Change_Of_Value = false; pObject->Write_Enabled = false; /* add to list */ index = Keylist_Data_Add(Object_List, object_instance, pObject); diff --git a/src/bacnet/basic/object/time_value.h b/src/bacnet/basic/object/time_value.h index f3dad507..956e5869 100644 --- a/src/bacnet/basic/object/time_value.h +++ b/src/bacnet/basic/object/time_value.h @@ -85,10 +85,22 @@ void Time_Value_Write_Enable(uint32_t instance); BACNET_STACK_EXPORT void Time_Value_Write_Disable(uint32_t instance); +BACNET_STACK_EXPORT +bool Time_Value_Encode_Value_List( + uint32_t object_instance, + BACNET_PROPERTY_VALUE * value_list); +BACNET_STACK_EXPORT +bool Time_Value_Change_Of_Value( + uint32_t instance); +BACNET_STACK_EXPORT +void Time_Value_Change_Of_Value_Clear( + uint32_t instance); + BACNET_STACK_EXPORT uint32_t Time_Value_Create(uint32_t object_instance); BACNET_STACK_EXPORT bool Time_Value_Delete(uint32_t object_instance); + BACNET_STACK_EXPORT void Time_Value_Cleanup(void); BACNET_STACK_EXPORT diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index 42bb4906..75b7298e 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -13,16 +13,15 @@ endif() # # options managed through Kconfig and use names CONFIG_* # - -set(BACNET_PROTOCOL_REVISION 19) - message(STATUS "BACNETSTACK: using cmake ${CMAKE_VERSION}") message(STATUS "BACNETSTACK: CMAKE_C_COMPILER_ID \"${CMAKE_C_COMPILER_ID}\"") message(STATUS "BACNETSTACK: CMAKE_C_COMPILER_VERSION \"${CMAKE_C_COMPILER_VERSION}\"") message(STATUS "BACNETSTACK: CMAKE_CXX_COMPILER_ID \"${CMAKE_CXX_COMPILER_ID}\"") message(STATUS "BACNETSTACK: CMAKE_CXX_COMPILER_VERSION \"${CMAKE_CXX_COMPILER_VERSION}\"") message(STATUS "BACNETSTACK: CMAKE_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}\"") -message(STATUS "BACNETSTACK: BACNET_PROTOCOL_REVISION \"${BACNET_PROTOCOL_REVISION}\"") +message(STATUS "BACNETSTACK: BACNET_VENDOR_NAME \"${CONFIG_BACNET_VENDOR_NAME}\"") +message(STATUS "BACNETSTACK: BACNET_VENDOR_IDENTIFIER \"${CONFIG_BACNET_VENDOR_IDENTIFIER}\"") +message(STATUS "BACNETSTACK: BACNET_PROTOCOL_REVISION \"${CONFIG_BACNET_PROTOCOL_REVISION}\"") message(STATUS "BACNETSTACK: BACDL_BIP6 \"${CONFIG_BACDL_BIP6}\"") message(STATUS "BACNETSTACK: BACDL_BIP \"${CONFIG_BACDL_BIP}\"") message(STATUS "BACNETSTACK: BACDL_ARCNET \"${CONFIG_BACDL_ARCNET}\"") @@ -30,6 +29,10 @@ message(STATUS "BACNETSTACK: BACDL_MSTP \"${CONFIG_BACDL_MSTP}\"") message(STATUS "BACNETSTACK: BACDL_ETHERNET \"${CONFIG_BACDL_ETHERNET}\"") message(STATUS "BACNETSTACK: BACDL_NONE \"${CONFIG_BACDL_NONE}\"") message(STATUS "BACNETSTACK: BACNET_ADDRESS_CACHE_FILE \"${CONFIG_BACNET_ADDRESS_CACHE_FILE}\"") +message(STATUS "BACNETSTACK: MAX_TSM_TRANSACTIONS \"${CONFIG_BACNET_MAX_TSM_TRANSACTIONS}\"") +message(STATUS "BACNETSTACK: MAX_ADDRESS_CACHE \"${CONFIG_BACNET_MAX_ADDRESS_CACHE}\"") +message(STATUS "BACNETSTACK: MAX_CHARACTER_STRING_BYTES \"${CONFIG_BACNET_MAX_CHARACTER_STRING_BYTES}\"") +message(STATUS "BACNETSTACK: MAX_OCTET_STRING_BYTES \"${CONFIG_BACNET_MAX_OCTET_STRING_BYTES}\"") #Do not allow in source builds set(CMAKE_DISABLE_SOURCE_CHANGES ON) @@ -339,7 +342,9 @@ set(BACNETSTACK_BASIC_SRCS $<$:${BACNETSTACK_SRC}/bacnet/basic/object/access_user.c> $<$:${BACNETSTACK_SRC}/bacnet/basic/object/access_zone.c> $<$:${BACNETSTACK_SRC}/bacnet/basic/object/acc.c> + $<$:${BACNETSTACK_SRC}/bacnet/basic/object/ai.c> $<$:${BACNETSTACK_SRC}/bacnet/basic/object/ao.c> + $<$:${BACNETSTACK_SRC}/bacnet/basic/object/av.c> $<$:${BACNETSTACK_SRC}/bacnet/basic/object/bacfile.c> $<$:${BACNETSTACK_SRC}/bacnet/basic/object/bi.c> $<$:${BACNETSTACK_SRC}/bacnet/basic/object/bo.c> @@ -433,7 +438,6 @@ list( add_subdirectory(subsys) - # # library # @@ -441,7 +445,13 @@ add_subdirectory(subsys) zephyr_library() zephyr_library_compile_definitions( + BACNET_VENDOR_ID=${CONFIG_BACNET_VENDOR_ID} + BACNET_VENDOR_NAME="${CONFIG_BACNET_VENDOR_NAME}" + BACNET_PROTOCOL_REVISION=${CONFIG_BACNET_PROTOCOL_REVISION} $<$:BACDL_BIP> + $<$:BACDL_BIP_PORT=${CONFIG_BACDL_BIP_PORT}> + $<$:MAX_BBMD_ENTRIES=${CONFIG_MAX_BBMD_ENTRIES}> + $<$:MAX_FD_ENTRIES=${CONFIG_MAX_FD_ENTRIES}> $<$:BACDL_BIP6> $<$:BACDL_ARCNET> $<$:BACDL_MSTP> @@ -453,7 +463,11 @@ zephyr_library_compile_definitions( $<$:BACAPP_PRINT_ENABLED=1> $<$:BACAPP_SNPRINTF_ENABLED=1> $<$:BACNET_ADDRESS_CACHE_FILE=1> - ) + MAX_TSM_TRANSACTIONS=${CONFIG_BACNET_MAX_TSM_TRANSACTIONS} + MAX_ADDRESS_CACHE=${CONFIG_BACNET_MAX_ADDRESS_CACHE} + MAX_CHARACTER_STRING_BYTES=${CONFIG_BACNET_MAX_CHARACTER_STRING_BYTES} + MAX_OCTET_STRING_BYTES=${CONFIG_BACNET_MAX_OCTET_STRING_BYTES} +) zephyr_library_sources( ${BACNETSTACK_SRCS} @@ -466,8 +480,13 @@ zephyr_include_directories( target_compile_definitions( app PRIVATE - BACNET_PROTOCOL_REVISION=${BACNET_PROTOCOL_REVISION} + BACNET_VENDOR_ID=${CONFIG_BACNET_VENDOR_IDENTIFIER} + BACNET_VENDOR_NAME="${CONFIG_BACNET_VENDOR_NAME}" + BACNET_PROTOCOL_REVISION=${CONFIG_BACNET_PROTOCOL_REVISION} $<$:BACDL_BIP> + $<$:BACDL_BIP_PORT=${CONFIG_BACDL_BIP_PORT}> + $<$:MAX_BBMD_ENTRIES=${CONFIG_MAX_BBMD_ENTRIES}> + $<$:MAX_FD_ENTRIES=${CONFIG_MAX_FD_ENTRIES}> $<$:BACDL_BIP6> $<$:BACDL_ARCNET> $<$:BACDL_MSTP> @@ -478,6 +497,10 @@ target_compile_definitions( $<$:BACAPP_PRINT_ENABLED=1> $<$:BACAPP_SNPRINTF_ENABLED=1> $<$:BACNET_ADDRESS_CACHE_FILE=1> + MAX_TSM_TRANSACTIONS=${CONFIG_BACNET_MAX_TSM_TRANSACTIONS} + MAX_ADDRESS_CACHE=${CONFIG_BACNET_MAX_ADDRESS_CACHE} + MAX_CHARACTER_STRING_BYTES=${CONFIG_BACNET_MAX_CHARACTER_STRING_BYTES} + MAX_OCTET_STRING_BYTES=${CONFIG_BACNET_MAX_OCTET_STRING_BYTES} BACNET_STACK_STATIC_DEFINE PRINT_ENABLED=1 ) @@ -485,4 +508,4 @@ target_compile_definitions( zephyr_compile_definitions( BACNET_CONFIG_H=1 # Use ports/zephyr/bacnet-config.h ) - + \ No newline at end of file diff --git a/zephyr/Kconfig b/zephyr/Kconfig index 93d28fac..3dfab625 100644 --- a/zephyr/Kconfig +++ b/zephyr/Kconfig @@ -16,6 +16,24 @@ module-str = Log level for BACnet module-help = Enable BACnet library to output debug messages source "$(ZEPHYR_BASE)/subsys/logging/Kconfig.template.log_config" +config BACNET_VENDOR_NAME + string "BACnet Vendor Name" + default "BACnet Stack at SourceForge" + help + BACnet Vendor Name string + +config BACNET_VENDOR_IDENTIFIER + int "BACnet Vendor Identifier" + default 260 + help + BACnet Vendir Identifier + +config BACNET_PROTOCOL_REVISION + int "BACnet Stack protocol-revision number" + default 24 + help + BACnet Stack protocol-revision number + config BAC_ROUTING bool "BACnet Routing" help @@ -68,6 +86,20 @@ config BACDL_BIP_PORT help UDP port to listen on (default=47808) +config MAX_BBMD_ENTRIES + int "Maximum number of Broadcast Device Table entries" + default 5 + depends on BACDL_BIP + help + Maximum number of Broadcast Device Table entries + +config MAX_FD_ENTRIES + int "Maximum number of Foreign Device Table entries" + default 5 + depends on BACDL_BIP + help + Maximum number of Foreign Device Table entries + config BACDL_BIP_ADDRESS_INDEX int "Address index" depends on BACDL_BIP @@ -101,6 +133,30 @@ config BACDL_BIP6_PORT help UDP port to listen on (default=47808) +config BACNET_MAX_TSM_TRANSACTIONS + int "Number of initiated confirmed-message transactions" + default 1 + help + Number of initiated confirmed-message transactions + +config BACNET_MAX_ADDRESS_CACHE + int "Number of address entries for I-Am bindings" + default 1 + help + Number of address entries for I-Am bindings + +config BACNET_MAX_CHARACTER_STRING_BYTES + int "Maximum number of bytes in a BACnet character string" + default 64 + help + Maximum number of bytes in a BACnet character string + +config BACNET_MAX_OCTET_STRING_BYTES + int "Maximum number of bytes in a BACnet octet string" + default 64 + help + Maximum number of bytes in a BACnet octet string + config BACNET_ADDRESS_CACHE_FILE bool "BACnet Address Cache file functionality" help @@ -280,19 +336,19 @@ config BACNET_BASIC_OBJECT_POSITIVE_INTEGER_VALUE help Use the BACnet basic positive-integer value object -config CONFIG_BACNET_BASIC_OBJECT_SCHEDULE +config BACNET_BASIC_OBJECT_SCHEDULE bool "Use the BACnet basic schedule object" default false help Use the BACnet basic schedule object -config CONFIG_BACNET_BASIC_OBJECT_TIME_VALUE +config BACNET_BASIC_OBJECT_TIME_VALUE bool "Use the BACnet basic time value object" default false help Use the BACnet basic time value object -config CONFIG_BACNET_BASIC_OBJECT_TRENDLOG +config BACNET_BASIC_OBJECT_TRENDLOG bool "Use the BACnet basic trendlog object" default false help