From 6f7f3649a5bdd0178e1b1a7f262e960a151f4186 Mon Sep 17 00:00:00 2001 From: Steve Karg Date: Tue, 25 Mar 2025 10:32:11 -0500 Subject: [PATCH] Bugfix/read range trend log buffer (#947) * Fixed ReadRange app to read and pretty-print a Trend Log log-buffer --- CMakeLists.txt | 2 + apps/readrange/main.c | 24 +- src/bacnet/bacapp.c | 241 ++++- src/bacnet/bacapp.h | 4 + src/bacnet/bacdcode.c | 44 +- src/bacnet/bacdcode.h | 7 +- src/bacnet/bacenum.h | 19 +- src/bacnet/baclog.c | 858 ++++++++++++++++++ src/bacnet/baclog.h | 107 +++ src/bacnet/bactext.c | 22 + src/bacnet/bactext.h | 3 + src/bacnet/basic/service/h_rr_a.c | 63 +- src/bacnet/channel_value.c | 2 +- src/bacnet/channel_value.h | 3 +- src/bacnet/config.h | 5 +- src/bacnet/readrange.c | 21 +- test/CMakeLists.txt | 1 + test/bacnet/access_rule/CMakeLists.txt | 1 + test/bacnet/bacapp/CMakeLists.txt | 1 + test/bacnet/bacdest/CMakeLists.txt | 1 + test/bacnet/bacdevobjpropref/CMakeLists.txt | 1 + test/bacnet/baclog/CMakeLists.txt | 70 ++ test/bacnet/baclog/src/main.c | 140 +++ test/bacnet/bactimevalue/CMakeLists.txt | 1 + .../basic/binding/address/CMakeLists.txt | 1 + test/bacnet/basic/object/acc/CMakeLists.txt | 1 + .../object/access_credential/CMakeLists.txt | 1 + .../basic/object/access_door/CMakeLists.txt | 1 + .../basic/object/access_point/CMakeLists.txt | 1 + .../basic/object/access_rights/CMakeLists.txt | 1 + .../basic/object/access_user/CMakeLists.txt | 1 + .../basic/object/access_zone/CMakeLists.txt | 1 + test/bacnet/basic/object/ai/CMakeLists.txt | 1 + test/bacnet/basic/object/ao/CMakeLists.txt | 1 + test/bacnet/basic/object/av/CMakeLists.txt | 1 + .../basic/object/bacfile/CMakeLists.txt | 1 + test/bacnet/basic/object/bi/CMakeLists.txt | 1 + .../object/bitstring_value/CMakeLists.txt | 1 + test/bacnet/basic/object/blo/CMakeLists.txt | 1 + test/bacnet/basic/object/bo/CMakeLists.txt | 1 + test/bacnet/basic/object/bv/CMakeLists.txt | 1 + .../basic/object/calendar/CMakeLists.txt | 1 + .../basic/object/channel/CMakeLists.txt | 1 + .../basic/object/color_object/CMakeLists.txt | 1 + .../object/color_temperature/CMakeLists.txt | 1 + .../basic/object/command/CMakeLists.txt | 1 + .../credential_data_input/CMakeLists.txt | 1 + test/bacnet/basic/object/csv/CMakeLists.txt | 1 + .../bacnet/basic/object/device/CMakeLists.txt | 1 + test/bacnet/basic/object/iv/CMakeLists.txt | 1 + test/bacnet/basic/object/lc/CMakeLists.txt | 1 + test/bacnet/basic/object/lo/CMakeLists.txt | 1 + test/bacnet/basic/object/lsp/CMakeLists.txt | 1 + test/bacnet/basic/object/lsz/CMakeLists.txt | 1 + .../basic/object/ms-input/CMakeLists.txt | 1 + test/bacnet/basic/object/mso/CMakeLists.txt | 1 + test/bacnet/basic/object/msv/CMakeLists.txt | 1 + test/bacnet/basic/object/nc/CMakeLists.txt | 1 + .../basic/object/netport/CMakeLists.txt | 2 + test/bacnet/basic/object/osv/CMakeLists.txt | 1 + test/bacnet/basic/object/piv/CMakeLists.txt | 1 + .../basic/object/program/CMakeLists.txt | 1 + .../basic/object/schedule/CMakeLists.txt | 1 + .../object/structured_view/CMakeLists.txt | 1 + .../basic/object/time_value/CMakeLists.txt | 1 + .../basic/object/trendlog/CMakeLists.txt | 1 + test/bacnet/cov/CMakeLists.txt | 1 + test/bacnet/create_object/CMakeLists.txt | 1 + .../datalink/bsc-datalink/CMakeLists.txt | 1 + test/bacnet/datalink/bsc-node/CMakeLists.txt | 1 + .../bacnet/datalink/bsc-socket/CMakeLists.txt | 1 + test/bacnet/datalink/hub-sc/CMakeLists.txt | 1 + test/bacnet/delete_object/CMakeLists.txt | 1 + test/bacnet/event/CMakeLists.txt | 1 + test/bacnet/getalarm/CMakeLists.txt | 1 + test/bacnet/getevent/CMakeLists.txt | 1 + test/bacnet/hostnport/CMakeLists.txt | 1 + test/bacnet/list_element/CMakeLists.txt | 1 + test/bacnet/lso/CMakeLists.txt | 1 + test/bacnet/ptransfer/CMakeLists.txt | 1 + test/bacnet/rpm/CMakeLists.txt | 1 + test/bacnet/secure_connect/CMakeLists.txt | 1 + test/bacnet/specialevent/CMakeLists.txt | 1 + test/bacnet/timesync/CMakeLists.txt | 1 + test/bacnet/weeklyschedule/CMakeLists.txt | 1 + test/bacnet/wp/CMakeLists.txt | 1 + test/bacnet/wpm/CMakeLists.txt | 1 + test/bacnet/write_group/CMakeLists.txt | 1 + 88 files changed, 1637 insertions(+), 69 deletions(-) create mode 100644 src/bacnet/baclog.c create mode 100644 src/bacnet/baclog.h create mode 100644 test/bacnet/baclog/CMakeLists.txt create mode 100644 test/bacnet/baclog/src/main.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 3253e76c..7acf0b2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -265,6 +265,8 @@ add_library(${PROJECT_NAME} src/bacnet/bacerror.h src/bacnet/bacint.c src/bacnet/bacint.h + src/bacnet/baclog.c + src/bacnet/baclog.h src/bacnet/bacprop.c src/bacnet/bacprop.h src/bacnet/bacpropstates.c diff --git a/apps/readrange/main.c b/apps/readrange/main.c index d1f224e0..e097f156 100644 --- a/apps/readrange/main.c +++ b/apps/readrange/main.c @@ -118,7 +118,7 @@ static void Init_Service_Handlers(void) SERVICE_CONFIRMED_READ_RANGE, handler_read_range_ack); /* handle any errors coming back */ - apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler); + apdu_set_error_handler(SERVICE_CONFIRMED_READ_RANGE, MyErrorHandler); apdu_set_abort_handler(MyAbortHandler); apdu_set_reject_handler(MyRejectHandler); } @@ -173,15 +173,19 @@ static void print_help(const char *filename) printf("count:\n" "This integer parameter is the number of elements to read.\n"); printf("\n"); - printf("Example:\n" - "If you want read the Log_Buffer of Trend Log 2\n" - "in Device 123, from starting position 1 and read 10 entries,\n" + printf("Examples:\n" + "If you want read the Log_Buffer of Trend Log 2 in Device 123," + "from starting position 1 and read 10 entries,\n" "you could send the following commands:\n"); printf("%s 123 trend-log 2 log-buffer 1 1 10\n", filename); - printf("%s 123 trend-log 2 log-buffer 2 1 10\n", filename); - printf("%s 123 trend-log 2 log-buffer 3 1/1/2014 00:00:01 10\n", filename); printf("%s 123 20 2 131 1 1 10\n", filename); + printf("from starting sequence 1 and read 10 entries,\n" + "you could send the following commands:\n"); + printf("%s 123 trend-log 2 log-buffer 2 1 10\n", filename); printf("%s 123 20 2 131 2 1 10\n", filename); + printf("from starting date/time 1/1/2014 00:00:01 and read 10 entries,\n" + "you could send the following commands:\n"); + printf("%s 123 trend-log 2 log-buffer 3 1/1/2014 00:00:01 10\n", filename); printf("%s 123 20 2 131 3 1/1/2014 00:00:01 10\n", filename); } @@ -221,7 +225,7 @@ int main(int argc, char *argv[]) return 0; } } - if (argc < 5) { + if (argc < 6) { print_usage(filename); return 0; } @@ -247,7 +251,7 @@ int main(int argc, char *argv[]) return 1; } if (Target_Object_Range_Type == 1) { - if (argc < 7) { + if (argc < 8) { print_usage(filename); return 0; } @@ -257,7 +261,7 @@ int main(int argc, char *argv[]) RR_Request.Range.RefIndex = Target_Object_Index; RR_Request.Count = Target_Object_Count; } else if (Target_Object_Range_Type == 2) { - if (argc < 7) { + if (argc < 8) { print_usage(filename); return 0; } @@ -267,7 +271,7 @@ int main(int argc, char *argv[]) RR_Request.Range.RefSeqNum = Target_Object_Index; RR_Request.Count = Target_Object_Count; } else if (Target_Object_Range_Type == 3) { - if (argc < 8) { + if (argc < 9) { print_usage(filename); return 0; } diff --git a/src/bacnet/bacapp.c b/src/bacnet/bacapp.c index 78f1df85..7a9a0b4d 100644 --- a/src/bacnet/bacapp.c +++ b/src/bacnet/bacapp.c @@ -23,6 +23,7 @@ #include "bacnet/access_rule.h" #include "bacnet/bacdcode.h" #include "bacnet/bacint.h" +#include "bacnet/baclog.h" #include "bacnet/bacreal.h" #include "bacnet/bacapp.h" #include "bacnet/bactext.h" @@ -527,6 +528,13 @@ int bacapp_encode_application_data( apdu, &value->type.Channel_Value); break; #endif +#if defined(BACAPP_LOG_RECORD) + case BACNET_APPLICATION_TAG_LOG_RECORD: + /* BACnetLogRecord */ + apdu_len = bacnet_log_record_value_encode( + apdu, &value->type.Log_Record); + break; +#endif #if defined(BACAPP_SECURE_CONNECT) case BACNET_APPLICATION_TAG_SC_FAILED_CONNECTION_REQUEST: apdu_len = bacapp_encode_SCFailedConnectionRequest( @@ -960,6 +968,7 @@ int bacapp_encode_context_data_value( case BACNET_APPLICATION_TAG_BDT_ENTRY: case BACNET_APPLICATION_TAG_FDT_ENTRY: case BACNET_APPLICATION_TAG_ACTION_COMMAND: + case BACNET_APPLICATION_TAG_LOG_RECORD: case BACNET_APPLICATION_TAG_SCALE: case BACNET_APPLICATION_TAG_SHED_LEVEL: case BACNET_APPLICATION_TAG_ACCESS_RULE: @@ -1165,6 +1174,8 @@ static int decode_priority_array_value( } apdu_len += len; } else +#else + (void)object_type; #endif { apdu_len = bacapp_decode_application_data(apdu, apdu_size, value); @@ -1319,6 +1330,9 @@ int bacapp_known_property_tag( /* FIXME: BACnetAddressBinding */ return -1; + case PROP_LOG_BUFFER: + /* BACnetLogRecord */ + return BACNET_APPLICATION_TAG_LOG_RECORD; case PROP_ACTION: /* BACnetActionCommand */ return BACNET_APPLICATION_TAG_ACTION_COMMAND; @@ -1364,6 +1378,8 @@ int bacapp_known_property_tag( return -1; } #else + (void)object_type; + (void)property; return -1; #endif } @@ -1670,6 +1686,13 @@ int bacapp_decode_application_tag_value( apdu, apdu_size, &value->type.Channel_Value); break; #endif +#if defined(BACAPP_LOG_RECORD) + case BACNET_APPLICATION_TAG_LOG_RECORD: + /* BACnetLogRecord */ + apdu_len = bacnet_log_record_decode( + apdu, apdu_size, &value->type.Log_Record); + break; +#endif #if defined(BACAPP_SECURE_CONNECT) case BACNET_APPLICATION_TAG_SC_FAILED_CONNECTION_REQUEST: apdu_len = bacapp_decode_SCFailedConnectionRequest( @@ -2161,6 +2184,42 @@ static int bacapp_snprintf_double(char *str, size_t str_len, double value) } #endif +#if defined(BACAPP_BIT_STRING) +/** + * @brief Print a bit string value to a string for EPICS + * @param str - destination string, or NULL for length only + * @param str_len - length of the destination string, or 0 for length only + * @param value - bit string value to print + * @return number of characters written + */ +static int bacapp_snprintf_bit_string( + char *str, size_t str_len, const BACNET_BIT_STRING *value) +{ + int ret_val = 0; + int len = 0; + int slen = 0; + int i = 0; + + len = bitstring_bits_used(value); + slen = bacapp_snprintf(str, str_len, "{"); + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + for (i = 0; i < len; i++) { + bool bit; + bit = bitstring_bit(value, (uint8_t)i); + slen = bacapp_snprintf(str, str_len, "%s", bit ? "true" : "false"); + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + if (i < (len - 1)) { + slen = bacapp_snprintf(str, str_len, ","); + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + } + } + slen = bacapp_snprintf(str, str_len, "}"); + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + + return ret_val; +} +#endif + #if defined(BACAPP_ENUMERATED) /** * @brief Print an enumerated value to a string for EPICS @@ -2311,6 +2370,44 @@ bacapp_snprintf_date(char *str, size_t str_len, const BACNET_DATE *bdate) } #endif +#if defined(BACAPP_LOG_RECORD) +/** + * @brief Print a date value to a string as numeric + * @param str - destination string, or NULL for length only + * @param str_len - length of the destination string, or 0 for length only + * @param bdate - date value to print + * @return number of characters written + * @note Numeric will be in the format: yyyy-mm-dd + */ +static int bacapp_snprintf_date_numeric( + char *str, size_t str_len, const BACNET_DATE *bdate) +{ + int ret_val = 0; + int slen = 0; + + if (bdate->year == 2155) { + slen = bacapp_snprintf(str, str_len, "****-"); + } else { + slen = bacapp_snprintf(str, str_len, "%04u-", (unsigned)bdate->year); + } + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + if (bdate->month == 255) { + slen = bacapp_snprintf(str, str_len, "**-"); + } else { + slen = bacapp_snprintf(str, str_len, "%02u-", (unsigned)bdate->month); + } + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + if (bdate->day == 255) { + slen = bacapp_snprintf(str, str_len, "**"); + } else { + slen = bacapp_snprintf(str, str_len, "%02u", (unsigned)bdate->day); + } + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + + return ret_val; +} +#endif + #if defined(BACAPP_TIME) /** * @brief Print a time value to a string for EPICS @@ -2422,6 +2519,34 @@ static int bacapp_snprintf_datetime( } #endif +#if defined(BACAPP_LOG_RECORD) +/** + * @brief Print a value to a string as numeric + * @param str - destination string, or NULL for length only + * @param str_len - length of the destination string, or 0 for length only + * @param value - value to print + * @return number of characters written + */ +static int bacapp_snprintf_datetime_numeric( + char *str, size_t str_len, const BACNET_DATE_TIME *value) +{ + int ret_val = 0; + int slen = 0; + + slen = bacapp_snprintf(str, str_len, "{"); + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + slen = bacapp_snprintf_date_numeric(str, str_len, &value->date); + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + slen = bacapp_snprintf(str, str_len, "-"); + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + slen = bacapp_snprintf_time(str, str_len, &value->time); + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + ret_val += bacapp_snprintf(str, str_len, "}"); + + return ret_val; +} +#endif + #if defined(BACAPP_DATERANGE) || defined(BACAPP_CALENDAR_ENTRY) /** * @brief Print a value to a string for EPICS @@ -2924,6 +3049,86 @@ bool bacapp_channel_value_copy( } #endif +#if defined(BACAPP_LOG_RECORD) +/** + * @brief Print a value to a string for EPICS + * @param str - destination string, or NULL for length only + * @param str_len - length of the destination string, or 0 for length only + * @param value - value to be printed + * @return number of characters written to the string + */ +static int bacapp_snprintf_log_record( + char *str, size_t str_len, const BACNET_LOG_RECORD *value) +{ + int ret_val = 0, slen; + BACNET_BIT_STRING bitstring; + + slen = bacapp_snprintf(str, str_len, "{"); + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + slen = bacapp_snprintf_datetime_numeric(str, str_len, &value->timestamp); + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + if (value->tag < BACNET_LOG_DATUM_MAX) { + slen = bacapp_snprintf( + str, str_len, ", %s:", bactext_log_datum_name(value->tag)); + } else { + slen = + bacapp_snprintf(str, str_len, ", :", (unsigned)value->tag); + } + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + switch (value->tag) { + case BACNET_LOG_DATUM_STATUS: + bitstring_init(&bitstring); + bitstring_set_bits_used(&bitstring, 1, 8 - 3); + bitstring_set_octet(&bitstring, 0, value->log_datum.log_status); + slen = bacapp_snprintf_bit_string(str, str_len, &bitstring); + break; + case BACNET_LOG_DATUM_BOOLEAN: + slen = bacapp_snprintf_boolean( + str, str_len, value->log_datum.boolean_value); + break; + case BACNET_LOG_DATUM_REAL: + slen = + bacapp_snprintf_real(str, str_len, value->log_datum.real_value); + break; + case BACNET_LOG_DATUM_ENUMERATED: + slen = bacapp_snprintf( + str, str_len, "%lu", + (unsigned long)value->log_datum.enumerated_value); + break; + case BACNET_LOG_DATUM_UNSIGNED: + slen = bacapp_snprintf_unsigned_integer( + str, str_len, value->log_datum.unsigned_value); + break; + case BACNET_LOG_DATUM_SIGNED: + slen = bacapp_snprintf_signed_integer( + str, str_len, value->log_datum.integer_value); + break; + case BACNET_LOG_DATUM_NULL: + slen = bacapp_snprintf_null(str, str_len); + break; + case BACNET_LOG_DATUM_FAILURE: + slen = bacapp_snprintf( + str, str_len, "%s,%s", + bactext_error_class_name(value->log_datum.failure.error_class), + bactext_error_code_name(value->log_datum.failure.error_code)); + break; + case BACNET_LOG_DATUM_TIME_CHANGE: + slen = bacapp_snprintf_real( + str, str_len, value->log_datum.time_change); + break; + default: + slen = 0; + break; + } + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + /* FIXME: optional status flags */ + slen = bacapp_snprintf(str, str_len, "}"); + ret_val += bacapp_snprintf_shift(slen, &str, &str_len); + + return ret_val; +} +#endif + #if defined(BACAPP_WEEKLY_SCHEDULE) /** * @brief Print a weekly schedule value to a string for EPICS @@ -3520,22 +3725,8 @@ int bacapp_snprintf_value( #endif #if defined(BACAPP_BIT_STRING) case BACNET_APPLICATION_TAG_BIT_STRING: - len = bitstring_bits_used(&value->type.Bit_String); - slen = bacapp_snprintf(str, str_len, "{"); - ret_val += bacapp_snprintf_shift(slen, &str, &str_len); - for (i = 0; i < len; i++) { - bool bit; - bit = bitstring_bit(&value->type.Bit_String, (uint8_t)i); - slen = bacapp_snprintf( - str, str_len, "%s", bit ? "true" : "false"); - ret_val += bacapp_snprintf_shift(slen, &str, &str_len); - if (i < (len - 1)) { - slen = bacapp_snprintf(str, str_len, ","); - ret_val += bacapp_snprintf_shift(slen, &str, &str_len); - } - } - slen = bacapp_snprintf(str, str_len, "}"); - ret_val += slen; + ret_val = bacapp_snprintf_bit_string( + str, str_len, &value->type.Bit_String); break; #endif #if defined(BACAPP_ENUMERATED) @@ -3731,6 +3922,12 @@ int bacapp_snprintf_value( ret_val = bacapp_snprintf_channel_value( str, str_len, &value->type.Channel_Value); break; +#endif +#if defined(BACAPP_LOG_RECORD) + case BACNET_APPLICATION_TAG_LOG_RECORD: + ret_val = bacapp_snprintf_log_record( + str, str_len, &value->type.Log_Record); + break; #endif case BACNET_APPLICATION_TAG_EMPTYLIST: ret_val = bacapp_snprintf(str, str_len, "{}"); @@ -4495,6 +4692,12 @@ bool bacapp_parse_application_data( bacnet_channel_value_from_ascii( &value->type.Channel_Value, argv); break; +#endif +#if defined(BACAPP_LOG_RECORD) + case BACNET_APPLICATION_TAG_LOG_RECORD: + status = bacnet_log_record_datum_from_ascii( + &value->type.Log_Record, argv); + break; #endif default: break; @@ -5060,6 +5263,12 @@ bool bacapp_same_value( &value->type.Channel_Value, &test_value->type.Channel_Value); break; +#endif +#if defined(BACAPP_LOG_RECORD) + case BACNET_APPLICATION_TAG_LOG_RECORD: + status = bacnet_log_record_same( + &value->type.Log_Record, &test_value->type.Log_Record); + break; #endif case BACNET_APPLICATION_TAG_EMPTYLIST: status = true; diff --git a/src/bacnet/bacapp.h b/src/bacnet/bacapp.h index 76bfc80e..541bbc6d 100644 --- a/src/bacnet/bacapp.h +++ b/src/bacnet/bacapp.h @@ -19,6 +19,7 @@ #include "bacnet/bacaction.h" #include "bacnet/bacdest.h" #include "bacnet/bacint.h" +#include "bacnet/baclog.h" #include "bacnet/bacstr.h" #include "bacnet/datetime.h" #include "bacnet/lighting.h" @@ -169,6 +170,9 @@ typedef struct BACnet_Application_Data_Value { #if defined(BACAPP_CHANNEL_VALUE) BACNET_CHANNEL_VALUE Channel_Value; #endif +#if defined(BACAPP_LOG_RECORD) + BACNET_LOG_RECORD Log_Record; +#endif #if defined(BACAPP_SECURE_CONNECT) BACNET_SC_FAILED_CONNECTION_REQUEST SC_Failed_Req; BACNET_SC_HUB_FUNCTION_CONNECTION_STATUS SC_Hub_Function_Status; diff --git a/src/bacnet/bacdcode.c b/src/bacnet/bacdcode.c index 08d417d0..cd86c3fd 100644 --- a/src/bacnet/bacdcode.c +++ b/src/bacnet/bacdcode.c @@ -1274,6 +1274,41 @@ int bacnet_boolean_application_decode( return apdu_len; } +/** + * @brief Decode a context boolean value. + * @param apdu Pointer to the encode buffer. + * @param apdu_size Number of bytes in the buffer. + * @param boolean_value Pointer to a boolean variable + * @note The Boolean datatype differs from the other datatypes + * in that the encoding of a context-tagged Boolean value is not the + * same as the encoding of an application-tagged Boolean value. + * This is done so that the application-tagged value may be encoded + * in a single octet, without a contents octet. While this same encoding + * could have been used for the context-tagged case, doing + * so would require that the context be known in order to distinguish + * between a length or a value in the length/value/type field. + * This was considered to be undesirable. + * @return number of bytes decoded, or 0 if errors occur + */ +int bacnet_boolean_context_value_decode( + const uint8_t *apdu, uint32_t apdu_size, bool *boolean_value) +{ + int len = 0; + + if (apdu && (apdu_size > 0)) { + if (boolean_value) { + if (apdu[0]) { + *boolean_value = true; + } else { + *boolean_value = false; + } + } + len = 1; + } + + return len; +} + /** * @brief Decode the Boolean Value when context encoded * From clause 20.2.3 Encoding of a Boolean Value @@ -1314,11 +1349,10 @@ int bacnet_boolean_context_decode( if (len > 0) { if (tag.context && (tag.number == tag_value)) { apdu_len = len; - if (apdu_len < apdu_size) { - if (boolean_value) { - *boolean_value = decode_context_boolean(&apdu[apdu_len]); - } - apdu_len++; + len = bacnet_boolean_context_value_decode( + &apdu[apdu_len], apdu_size - apdu_len, boolean_value); + if (len > 0) { + apdu_len += len; } else { apdu_len = BACNET_STATUS_ERROR; } diff --git a/src/bacnet/bacdcode.h b/src/bacnet/bacdcode.h index 36f25e00..43e59a7e 100644 --- a/src/bacnet/bacdcode.h +++ b/src/bacnet/bacdcode.h @@ -186,11 +186,14 @@ int bacnet_boolean_application_encode( uint8_t *apdu, uint32_t apdu_size, bool value); BACNET_STACK_EXPORT int bacnet_boolean_application_decode( - const uint8_t *apdu, uint32_t apdu_len_max, bool *value); + const uint8_t *apdu, uint32_t apdu_size, bool *value); +BACNET_STACK_EXPORT +int bacnet_boolean_context_value_decode( + const uint8_t *apdu, uint32_t apdu_size, bool *boolean_value); BACNET_STACK_EXPORT int bacnet_boolean_context_decode( const uint8_t *apdu, - uint32_t apdu_len_max, + uint32_t apdu_size, uint8_t tag_value, bool *boolean_value); diff --git a/src/bacnet/bacenum.h b/src/bacnet/bacenum.h index f88beca6..1b06768d 100644 --- a/src/bacnet/bacenum.h +++ b/src/bacnet/bacenum.h @@ -1621,7 +1621,9 @@ typedef enum { /* BACnetAccessRule */ BACNET_APPLICATION_TAG_ACCESS_RULE, /* BACnetChannelValue */ - BACNET_APPLICATION_TAG_CHANNEL_VALUE + BACNET_APPLICATION_TAG_CHANNEL_VALUE, + /* BACnetLogRecord */ + BACNET_APPLICATION_TAG_LOG_RECORD } BACNET_APPLICATION_TAG; /* note: these are not the real values, */ @@ -1805,6 +1807,21 @@ typedef enum { LOGGING_TYPE_TRIGGERED = 2 } BACNET_LOGGING_TYPE; +typedef enum BACnetLogDatum { + BACNET_LOG_DATUM_STATUS = 0, + BACNET_LOG_DATUM_BOOLEAN = 1, + BACNET_LOG_DATUM_REAL = 2, + BACNET_LOG_DATUM_ENUMERATED = 3, + BACNET_LOG_DATUM_UNSIGNED = 4, + BACNET_LOG_DATUM_SIGNED = 5, + BACNET_LOG_DATUM_BITSTRING = 6, + BACNET_LOG_DATUM_NULL = 7, + BACNET_LOG_DATUM_FAILURE = 8, + BACNET_LOG_DATUM_TIME_CHANGE = 9, + BACNET_LOG_DATUM_ANY = 10, + BACNET_LOG_DATUM_MAX = 11 +} BACNET_LOG_DATUM; + typedef enum { ACKNOWLEDGMENT_FILTER_ALL = 0, ACKNOWLEDGMENT_FILTER_ACKED = 1, diff --git a/src/bacnet/baclog.c b/src/bacnet/baclog.c new file mode 100644 index 00000000..f7bcd5ba --- /dev/null +++ b/src/bacnet/baclog.c @@ -0,0 +1,858 @@ +/** + * @file + * @brief BACnetLogRecord data type encoding and decoding + * @author Steve Karg + * @date 2025 + * @copyright SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0 + */ +#include +#include +#include +#include +#include +#include +/* BACnet Stack defines - first */ +#include "bacnet/bacdef.h" +/* BACnet Stack API */ +#include "bacnet/bacdcode.h" +#include "bacnet/bacstr.h" +#include "bacnet/bacint.h" +#include "bacnet/bacreal.h" +#include "bacnet/datetime.h" +/* me! */ +#include "bacnet/baclog.h" + +/** + * @brief Encode a given BACnetLogRecord value + * @param apdu - APDU buffer for storing the encoded data, or NULL for length + * @param value - BACNET_LOG_RECORD value + * @return number of bytes in the APDU, or 0 on error + */ +int bacnet_log_record_value_encode( + uint8_t *apdu, const BACNET_LOG_RECORD *value) +{ + int apdu_len = 0, len; + BACNET_BIT_STRING bitstring; + uint8_t i = 0; + + if (!value) { + return 0; + } + /* time stamp [0] */ + len = bacapp_encode_context_datetime(apdu, 0, &value->timestamp); + apdu_len += len; + if (apdu) { + apdu += len; + } + /* log-datum [1] */ + len = encode_opening_tag(apdu, 1); + apdu_len += len; + if (apdu) { + apdu += len; + } + switch (value->tag) { + case BACNET_LOG_DATUM_STATUS: + /* log-status [0] BACnetLogStatus */ + bitstring_init(&bitstring); + bitstring_set_bits_used(&bitstring, 1, 8 - 3); + bitstring_set_octet(&bitstring, 0, value->log_datum.log_status); + len = encode_context_bitstring(apdu, value->tag, &bitstring); + break; + case BACNET_LOG_DATUM_BOOLEAN: + /* boolean-value [1] BOOLEAN */ + len = encode_context_boolean( + apdu, value->tag, value->log_datum.boolean_value); + break; + case BACNET_LOG_DATUM_REAL: + /* real-value [2] REAL */ + len = encode_context_real( + apdu, value->tag, value->log_datum.real_value); + break; + case BACNET_LOG_DATUM_ENUMERATED: + /* enumerated-value [3] ENUMERATED, + * -- Optionally limited to 32 bits */ + len = encode_context_enumerated( + apdu, value->tag, value->log_datum.enumerated_value); + break; + case BACNET_LOG_DATUM_UNSIGNED: + /* unsigned-value [4] Unsigned, + * -- Optionally limited to 32 bits*/ + len = encode_context_unsigned( + apdu, value->tag, value->log_datum.unsigned_value); + break; + case BACNET_LOG_DATUM_SIGNED: + /* integer-value [5] INTEGER, + * -- Optionally limited to 32 bits */ + len = encode_context_signed( + apdu, value->tag, value->log_datum.integer_value); + break; + case BACNET_LOG_DATUM_BITSTRING: + /* bitstring-value [6] BIT STRING, + * -- Optionally limited to 32 bits */ + bitstring_init(&bitstring); + bitstring_bits_used_set( + &bitstring, value->log_datum.bitstring_value.bits_used); + for (i = 0; i < BACNET_LOG_DATUM_BITSTRING_BYTES_MAX; i++) { + bitstring_set_octet( + &bitstring, i, value->log_datum.bitstring_value.value[i]); + } + len = encode_context_bitstring(apdu, value->tag, &bitstring); + break; + case BACNET_LOG_DATUM_NULL: + /* null-value [7] NULL */ + len = encode_context_null(apdu, value->tag); + break; + case BACNET_LOG_DATUM_FAILURE: + /* failure [8] Error */ + len = encode_opening_tag(apdu, value->tag); + apdu_len += len; + if (apdu) { + apdu += len; + } + len = encode_application_enumerated( + apdu, value->log_datum.failure.error_class); + apdu_len += len; + if (apdu) { + apdu += len; + } + len = encode_application_enumerated( + apdu, value->log_datum.failure.error_code); + apdu_len += len; + if (apdu) { + apdu += len; + } + len = encode_closing_tag(apdu, value->tag); + break; + + case BACNET_LOG_DATUM_TIME_CHANGE: + /* time-change [9] REAL */ + len = encode_context_real( + apdu, value->tag, value->log_datum.time_change); + break; + + case BACNET_LOG_DATUM_ANY: + /* we don't support this option */ + break; + + default: + break; + } + apdu_len += len; + if (apdu) { + apdu += len; + } + /* log-datum [1] */ + len = encode_closing_tag(apdu, 1); + apdu_len += len; + if (apdu) { + apdu += len; + } + /* status-flags [2] BACnetStatusFlags OPTIONAL */ + if (bacnet_log_record_status_flags_bit(value->status_flags, 7)) { + bitstring_init(&bitstring); + bitstring_set_bit( + &bitstring, STATUS_FLAG_IN_ALARM, + bacnet_log_record_status_flags_bit( + value->status_flags, STATUS_FLAG_IN_ALARM)); + bitstring_set_bit( + &bitstring, STATUS_FLAG_FAULT, + bacnet_log_record_status_flags_bit( + value->status_flags, STATUS_FLAG_FAULT)); + bitstring_set_bit( + &bitstring, STATUS_FLAG_OVERRIDDEN, + bacnet_log_record_status_flags_bit( + value->status_flags, STATUS_FLAG_OVERRIDDEN)); + bitstring_set_bit( + &bitstring, STATUS_FLAG_OUT_OF_SERVICE, + bacnet_log_record_status_flags_bit( + value->status_flags, STATUS_FLAG_OUT_OF_SERVICE)); + len = encode_context_bitstring(apdu, 2, &bitstring); + apdu_len += len; + } + + return apdu_len; +} + +/** + * @brief Encode a given channel value + * @param apdu - APDU buffer for storing the encoded data, or NULL for length + * @param apdu_size - size of the APDU buffer + * @param value - BACNET_LOG_RECORD value + * @return returns the number of apdu bytes consumed, + * or 0 if apdu_size is too small to fit the data + */ +int bacnet_log_record_encode( + uint8_t *apdu, size_t apdu_size, const BACNET_LOG_RECORD *value) +{ + size_t apdu_len = 0; /* total length of the apdu, return value */ + + apdu_len = bacnet_log_record_value_encode(NULL, value); + if (apdu_len > apdu_size) { + apdu_len = 0; + } else { + apdu_len = bacnet_log_record_value_encode(apdu, value); + } + + return apdu_len; +} + +/** + * @brief Decode a BACnetLogRecord log-datum value + * @param apdu - APDU buffer for decoding + * @param apdu_size - Count of valid bytes in the buffer + * @param tag_data_type - BACNET_LOG_DATUM tag + * @param len_value_type - length or value of the tag + * @param value - BACNET_LOG_RECORD value to store the decoded data + * @return number of bytes decoded (0 or more) or + * BACNET_STATUS_ERROR on error + */ +int bacnet_log_record_datum32_decode( + const uint8_t *apdu, + size_t apdu_size, + uint8_t tag_data_type, + uint32_t len_value_type, + BACNET_LOG_RECORD *value) +{ + int len = 0; + uint32_t enum_value = 0; + float real_value = 0.0; + BACNET_UNSIGNED_INTEGER unsigned_value = 0; + int32_t signed_value = 0; + BACNET_BIT_STRING bit_string = { 0 }; + bool boolean_value = false; + unsigned i; + + if (!apdu) { + return BACNET_STATUS_ERROR; + } + if (value) { + value->tag = tag_data_type; + } + switch (tag_data_type) { + case BACNET_LOG_DATUM_STATUS: + /* log-status [0] BACnetLogStatus BIT STRING */ + len = bacnet_bitstring_decode( + apdu, apdu_size, len_value_type, &bit_string); + if (len > 0) { + if (bit_string.bits_used > 3) { + return BACNET_STATUS_ERROR; + } + if (value) { + value->log_datum.log_status = bit_string.value[0]; + } + } else { + return BACNET_STATUS_ERROR; + } + break; + case BACNET_LOG_DATUM_BOOLEAN: + /* boolean-value [1] BOOLEAN */ + len = bacnet_boolean_context_value_decode( + apdu, apdu_size, &boolean_value); + if (value) { + value->log_datum.boolean_value = boolean_value; + } + break; + case BACNET_LOG_DATUM_REAL: + /* real-value [2] REAL */ + len = bacnet_real_decode( + apdu, apdu_size, len_value_type, &real_value); + if (len > 0) { + if (value) { + value->log_datum.real_value = real_value; + } + } else { + return BACNET_STATUS_ERROR; + } + break; + case BACNET_LOG_DATUM_ENUMERATED: + /* enumerated-value [3] ENUMERATED, + * -- Optionally limited to 32 bits */ + len = bacnet_enumerated_decode( + apdu, apdu_size, len_value_type, &enum_value); + if (len > 0) { + if (value) { + value->log_datum.enumerated_value = enum_value; + } + } else { + return BACNET_STATUS_ERROR; + } + break; + case BACNET_LOG_DATUM_UNSIGNED: + /* unsigned-value [4] Unsigned, + * -- Optionally limited to 32 bits*/ + len = bacnet_unsigned_decode( + apdu, apdu_size, len_value_type, &unsigned_value); + if (len > 0) { + if (value) { + value->log_datum.unsigned_value = unsigned_value; + } + } else { + return BACNET_STATUS_ERROR; + } + break; + case BACNET_LOG_DATUM_SIGNED: + /* integer-value [5] INTEGER, + * -- Optionally limited to 32 bits */ + len = bacnet_signed_decode( + apdu, apdu_size, len_value_type, &signed_value); + if (len > 0) { + if (value) { + value->log_datum.integer_value = signed_value; + } + } else { + return BACNET_STATUS_ERROR; + } + break; + case BACNET_LOG_DATUM_BITSTRING: + /* bitstring-value [6] BIT STRING, + * -- Optionally limited to 32 bits */ + len = bacnet_bitstring_decode( + apdu, apdu_size, len_value_type, &bit_string); + if (len > 0) { + if (bit_string.bits_used > 24) { + return BACNET_STATUS_ERROR; + } + if (value) { + value->log_datum.bitstring_value.bits_used = + bit_string.bits_used; + for (i = 0; i < BACNET_LOG_DATUM_BITSTRING_BYTES_MAX; i++) { + value->log_datum.bitstring_value.value[i] = + bit_string.value[i]; + } + } + } else { + return BACNET_STATUS_ERROR; + } + break; + case BACNET_LOG_DATUM_NULL: + /* null-value [7] NULL - nothing to do, value is tag */ + break; + case BACNET_LOG_DATUM_FAILURE: + /* open/close tagged values are not processed here */ + break; + case BACNET_LOG_DATUM_TIME_CHANGE: + /* time-change [9] REAL */ + len = bacnet_real_decode( + apdu, apdu_size, len_value_type, &real_value); + if (len > 0) { + if (value) { + value->log_datum.time_change = real_value; + } + } else { + return BACNET_STATUS_ERROR; + } + break; + case BACNET_LOG_DATUM_ANY: + /* we don't support this option */ + break; + + default: + break; + } + + return len; +} + +/** + * @brief Decode a BACnetLogRecord log-datum failure value + * @param apdu - APDU buffer for decoding + * @param apdu_size - Count of valid bytes in the buffer + * @param value - BACNET_LOG_RECORD value to store the decoded data + * @return number of bytes decoded (0 or more) or + * BACNET_STATUS_ERROR on error + */ +int bacnet_log_record_datum_failure_decode( + const uint8_t *apdu, size_t apdu_size, BACNET_LOG_RECORD *value) +{ + int len = 0; + int apdu_len = 0; + uint32_t enum_value = 0; + + if (!apdu) { + return BACNET_STATUS_ERROR; + } + /* failure [8] Error */ + len = bacnet_enumerated_application_decode( + apdu, apdu_size - apdu_len, &enum_value); + if (len > 0) { + apdu_len += len; + if (enum_value > UINT16_MAX) { + return BACNET_STATUS_ERROR; + } + if (value) { + value->log_datum.failure.error_class = (uint16_t)enum_value; + } + } else { + return BACNET_STATUS_ERROR; + } + len = bacnet_enumerated_application_decode( + &apdu[len], apdu_size - apdu_len, &enum_value); + if (len > 0) { + apdu_len += len; + if (enum_value > UINT16_MAX) { + return BACNET_STATUS_ERROR; + } + if (value) { + value->log_datum.failure.error_code = (uint16_t)enum_value; + } + } else { + return BACNET_STATUS_ERROR; + } + if (value) { + value->tag = BACNET_LOG_DATUM_FAILURE; + } + + return apdu_len; +} + +/** + * Set bits in the BACnetLogRecord datum bitstring (limited to 32-bits). + * + * @param bit_string Pointer to the bit string structure. + * @param bit_number Number of the bit 0..23 + * @param value Value true or false + */ +void bacnet_log_record_datum_bitstring_set( + struct bacnet_log_datum_bitstring *bit_string, + uint8_t bit_number, + bool value) +{ + unsigned byte_number = bit_number / 8; + uint8_t bit_mask = 1; + + if (bit_string) { + if (byte_number < BACNET_LOG_DATUM_BITSTRING_BYTES_MAX) { + /* set max bits used */ + if (bit_string->bits_used < (bit_number + 1)) { + bit_string->bits_used = bit_number + 1; + } + bit_mask = bit_mask << (bit_number - (byte_number * 8)); + if (value) { + bit_string->value[byte_number] |= bit_mask; + } else { + bit_string->value[byte_number] &= (~(bit_mask)); + } + } + } +} + +/** + * @brief Compare two BACnetLogRecord bitstring values + * @param value1 [in] The first BACnetLogRecord bitstring value + * @param value2 [in] The second BACnetLogRecord bitstring value + * @return true if the values are the same + */ +bool bacnet_log_record_datum_bitstring_same( + const struct bacnet_log_datum_bitstring *value1, + const struct bacnet_log_datum_bitstring *value2) +{ + unsigned i; + + if (value1->bits_used != value2->bits_used) { + return false; + } + for (i = 0; i < BACNET_LOG_DATUM_BITSTRING_BYTES_MAX; i++) { + if (value1->value[i] != value2->value[i]) { + return false; + } + } + return true; +} + +/** + * @brief Set bits in the BACnetLogRecord status_flags bitstring + * @note must be encoded/decoded in same bit order as a BACnetBitString + * @param status_flags pointer to status flags + * @param bit_number Number of the bit 0..7 + * @param value Value true or false + */ +void bacnet_log_record_status_flags_bit_set( + uint8_t *status_flags, uint8_t bit_number, bool value) +{ + uint8_t bit_mask = 1; + + if (bit_number > 7) { + return; + } + bit_mask = bit_mask << bit_number; + if (value) { + *status_flags |= bit_mask; + } else { + *status_flags &= (~(bit_mask)); + } +} + +/** + * @brief Return the value of a single bit out of the status_flags bit string. + * @note must be encoded/decoded in same bit order as a BACnetBitString + * @param bit_string Pointer to the bit string structure. + * @param bit_number Number of the bit 0..7 + * @return Value 0/1 + */ +bool bacnet_log_record_status_flags_bit( + uint8_t status_flags, uint8_t bit_number) +{ + bool value = false; + uint8_t bit_mask = 1; + + if (bit_number > 7) { + return false; + } + bit_mask = bit_mask << bit_number; + if (status_flags & bit_mask) { + value = true; + } + + return value; +} + +/** + * @brief Decode a given channel value + * @param apdu - APDU buffer for decoding + * @param apdu_size - Count of valid bytes in the buffer + * @param value - BACNET_LOG_RECORD value to store the decoded data + * @return number of bytes decoded or BACNET_STATUS_ERROR on error + */ +int bacnet_log_record_decode( + const uint8_t *apdu, size_t apdu_size, BACNET_LOG_RECORD *value) +{ + int len = 0; + int apdu_len = 0; + BACNET_TAG tag = { 0 }; + BACNET_DATE_TIME timestamp = { 0 }; + BACNET_BIT_STRING status_flags = { 0 }; + + if (!apdu) { + return BACNET_STATUS_ERROR; + } + /* time stamp [0] */ + len = bacnet_datetime_context_decode( + &apdu[apdu_len], apdu_size - apdu_len, 0, ×tamp); + if (len > 0) { + apdu_len += len; + if (value) { + datetime_copy(&value->timestamp, ×tamp); + } + } else { + return BACNET_STATUS_ERROR; + } + /* log-datum [1] - opening */ + if (bacnet_is_opening_tag_number( + &apdu[apdu_len], apdu_size - apdu_len, 1, &len)) { + apdu_len += len; + } else { + return BACNET_STATUS_ERROR; + } + len = bacnet_tag_decode(&apdu[apdu_len], apdu_size - apdu_len, &tag); + if (len > 0) { + apdu_len += len; + if (tag.opening) { + if (tag.number == BACNET_LOG_DATUM_FAILURE) { + len = bacnet_log_record_datum_failure_decode( + &apdu[apdu_len], apdu_size - apdu_len, value); + if (len > 0) { + apdu_len += len; + if (bacnet_is_closing_tag_number( + &apdu[apdu_len], apdu_size - apdu_len, tag.number, + &len)) { + apdu_len += len; + } else { + return BACNET_STATUS_ERROR; + } + } else { + return BACNET_STATUS_ERROR; + } + } else { + return BACNET_STATUS_ERROR; + } + } else if (tag.context) { + len = bacnet_log_record_datum32_decode( + &apdu[apdu_len], apdu_size - apdu_len, tag.number, + tag.len_value_type, value); + if (len >= 0) { + apdu_len += len; + } else { + return BACNET_STATUS_ERROR; + } + } else { + return BACNET_STATUS_ERROR; + } + } else { + return BACNET_STATUS_ERROR; + } + /* log-datum [1] - closing */ + if (bacnet_is_closing_tag_number( + &apdu[apdu_len], apdu_size - apdu_len, 1, &len)) { + apdu_len += len; + } else { + return BACNET_STATUS_ERROR; + } + /* status-flags [2] BACnetStatusFlags OPTIONAL */ + len = bacnet_bitstring_context_decode( + &apdu[apdu_len], apdu_size - apdu_len, 2, &status_flags); + if (len > 0) { + apdu_len += len; + if (status_flags.bits_used > 4) { + return BACNET_STATUS_ERROR; + } + if (value) { + value->status_flags = status_flags.value[0]; + bacnet_log_record_status_flags_bit_set( + &value->status_flags, 7, true); + } + } else if (len == 0) { + if (value) { + /* no status flags */ + value->status_flags = 0; + } + } else if (len < 0) { + return BACNET_STATUS_ERROR; + } + + return apdu_len; +} + +/** + * @brief Compare two BACnetLogRecord values + * @param value1 [in] The first BACnetLogRecord value + * @param value2 [in] The second BACnetLogRecord value + * @return true if the values are the same + */ +bool bacnet_log_record_same( + const BACNET_LOG_RECORD *value1, const BACNET_LOG_RECORD *value2) +{ + int diff; + + if (!value1 || !value2) { + return false; + } + if (value1->tag != value2->tag) { + return false; + } + diff = datetime_compare(&value1->timestamp, &value2->timestamp); + if (diff != 0) { + return false; + } + if (BIT_CHECK(value1->status_flags, 7)) { + /* optional status flags */ + if (BITMASK_CHECK(value1->status_flags, 0x0F) != + BITMASK_CHECK(value2->status_flags, 0x0F)) { + return false; + } + } + switch (value1->tag) { + case BACNET_LOG_DATUM_NULL: + return true; + case BACNET_LOG_DATUM_BOOLEAN: + return value1->log_datum.boolean_value == + value2->log_datum.boolean_value; + case BACNET_LOG_DATUM_UNSIGNED: + return value1->log_datum.unsigned_value == + value2->log_datum.unsigned_value; + case BACNET_LOG_DATUM_SIGNED: + return value1->log_datum.integer_value == + value2->log_datum.integer_value; + case BACNET_LOG_DATUM_REAL: + return !islessgreater( + value1->log_datum.real_value, value2->log_datum.real_value); + case BACNET_LOG_DATUM_BITSTRING: + return bacnet_log_record_datum_bitstring_same( + &value1->log_datum.bitstring_value, + &value2->log_datum.bitstring_value); + case BACNET_LOG_DATUM_ENUMERATED: + return value1->log_datum.enumerated_value == + value2->log_datum.enumerated_value; + case BACNET_LOG_DATUM_STATUS: + return value1->log_datum.log_status == value2->log_datum.log_status; + case BACNET_LOG_DATUM_TIME_CHANGE: + return !islessgreater( + value1->log_datum.time_change, value2->log_datum.time_change); + default: + break; + } + + return false; +} + +/** + * @brief Copy a BACnetLogDatum bitstring value + * @param dest [out] The destination BACnetLogDatum bitstring value + * @param src [in] The source BACnetLogDatum bitstring value + * @return true if the value was copied, else false + */ +static bool log_datum_bitstring_copy( + struct bacnet_log_datum_bitstring *dest, + const struct bacnet_log_datum_bitstring *src) +{ + unsigned i; + + if (!dest || !src) { + return false; + } + dest->bits_used = src->bits_used; + for (i = 0; i < BACNET_LOG_DATUM_BITSTRING_BYTES_MAX; i++) { + dest->value[i] = src->value[i]; + } + return true; +} + +/** + * @brief Copy a BACnetLogRecord to another + * @param value1 [in] The first BACnetLogRecord value + * @param value2 [in] The second BACnetLogRecord value + * @return true if the value was copied, else false + */ +bool bacnet_log_record_copy( + BACNET_LOG_RECORD *dest, const BACNET_LOG_RECORD *src) +{ + if (!dest || !src) { + return false; + } + dest->tag = src->tag; + dest->status_flags = src->status_flags; + datetime_copy(&dest->timestamp, &src->timestamp); + switch (src->tag) { + case BACNET_LOG_DATUM_NULL: + return true; + case BACNET_LOG_DATUM_BOOLEAN: + dest->log_datum.boolean_value = src->log_datum.boolean_value; + return true; + case BACNET_LOG_DATUM_UNSIGNED: + dest->log_datum.unsigned_value = src->log_datum.unsigned_value; + return true; + case BACNET_LOG_DATUM_SIGNED: + dest->log_datum.integer_value = src->log_datum.integer_value; + return true; + case BACNET_LOG_DATUM_REAL: + dest->log_datum.real_value = src->log_datum.real_value; + return true; + case BACNET_LOG_DATUM_BITSTRING: + return log_datum_bitstring_copy( + &dest->log_datum.bitstring_value, + &src->log_datum.bitstring_value); + case BACNET_LOG_DATUM_ENUMERATED: + dest->log_datum.enumerated_value = src->log_datum.enumerated_value; + return true; + case BACNET_LOG_DATUM_STATUS: + dest->log_datum.log_status = src->log_datum.log_status; + return true; + case BACNET_LOG_DATUM_TIME_CHANGE: + dest->log_datum.time_change = src->log_datum.time_change; + return true; + default: + break; + } + + return false; +} + +/** + * @brief Parse a string into a BACnetLogRecord structure + * @param value [out] The BACnetLogRecord value + * @param argv [in] The string to parse + * @return true on success, else false + */ +bool bacnet_log_record_datum_from_ascii( + BACNET_LOG_RECORD *value, const char *argv) +{ + bool status = false; + int count; + unsigned long unsigned_value; + long signed_value; + float single_value; + double double_value; + const char *negative; + const char *decimal_point; + const char *real_string; + + if (!value || !argv) { + return false; + } + if (!status) { + if (bacnet_stricmp(argv, "null") == 0) { + value->tag = BACNET_LOG_DATUM_NULL; + status = true; + } + } + if (!status) { + if (bacnet_stricmp(argv, "true") == 0) { + value->tag = BACNET_LOG_DATUM_BOOLEAN; + value->log_datum.boolean_value = true; + status = true; + } + } + if (!status) { + if (bacnet_stricmp(argv, "false") == 0) { + value->tag = BACNET_LOG_DATUM_BOOLEAN; + value->log_datum.boolean_value = false; + status = true; + } + } + if (!status) { + /* time_change */ + real_string = strchr(argv, 'T'); + if (!real_string) { + real_string = strchr(argv, 't'); + } + if (real_string) { + value->tag = BACNET_LOG_DATUM_TIME_CHANGE; + count = sscanf(argv + 1, "%f", &single_value); + if (count == 1) { + value->log_datum.real_value = single_value; + status = true; + } + } + } + if (!status) { + decimal_point = strchr(argv, '.'); + if (decimal_point) { + count = sscanf(argv, "%lf", &double_value); + if (count == 1) { + if (isgreaterequal(double_value, -FLT_MAX) && + islessequal(double_value, FLT_MAX)) { + value->tag = BACNET_LOG_DATUM_REAL; + value->log_datum.real_value = (float)double_value; + status = true; + } + } + } + } + if (!status) { + negative = strchr(argv, '-'); + if (negative) { + count = sscanf(argv, "%ld", &signed_value); + if (count == 1) { + value->tag = BACNET_LOG_DATUM_SIGNED; + value->log_datum.integer_value = signed_value; + status = true; + } + } + } + if (!status) { + count = sscanf(argv, "%lu", &unsigned_value); + if (count == 1) { + value->tag = BACNET_LOG_DATUM_UNSIGNED; + value->log_datum.unsigned_value = unsigned_value; + status = true; + } + } + + return status; +} + +/** + * @brief Convert an array of BACnetLogRecord to linked list + * @param array pointer to element zero of the array + * @param size number of elements in the array + */ +void bacnet_log_record_link_array(BACNET_LOG_RECORD *array, size_t size) +{ + size_t i = 0; + + for (i = 0; i < size; i++) { + if (i > 0) { + array[i - 1].next = &array[i]; + } + array[i].next = NULL; + } +} diff --git a/src/bacnet/baclog.h b/src/bacnet/baclog.h new file mode 100644 index 00000000..ed462897 --- /dev/null +++ b/src/bacnet/baclog.h @@ -0,0 +1,107 @@ +/** + * @file + * @brief BACnetLogRecord data type encoding and decoding + * @author Steve Karg + * @date 2025 + * @copyright SPDX-License-Identifier: MIT + */ +#ifndef BACNET_LOG_H +#define BACNET_LOG_H + +#include +#include +#include +/* BACnet Stack defines - first */ +#include "bacnet/bacdef.h" +/* BACnet datatypes */ +#include "bacnet/datetime.h" + +/* BACnetLogRecord log-datum failure Error */ +struct bacnet_log_datum_error { + uint16_t error_class; + uint16_t error_code; +}; + +/* BACnetLogRecord log-datum 32-bit bitstring (maps 24-bits) */ +#define BACNET_LOG_DATUM_BITSTRING_BYTES_MAX 3 +struct bacnet_log_datum_bitstring { + uint8_t bits_used; + uint8_t value[BACNET_LOG_DATUM_BITSTRING_BYTES_MAX]; +}; + +typedef struct BACnetLogRecord { + BACNET_DATE_TIME timestamp; + /* only 4 lower bits used; set bit-7 to include this optional data */ + uint8_t status_flags; + /* tag indicates which datum is used */ + uint8_t tag; + union { + uint8_t log_status; + uint8_t boolean_value; + float real_value; + uint32_t enumerated_value; + uint32_t unsigned_value; + int32_t integer_value; + struct bacnet_log_datum_bitstring bitstring_value; + struct bacnet_log_datum_error failure; + float time_change; + } log_datum; + struct BACnetLogRecord *next; +} BACNET_LOG_RECORD; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +BACNET_STACK_EXPORT +int bacnet_log_record_value_encode( + uint8_t *apdu, const BACNET_LOG_RECORD *value); +BACNET_STACK_EXPORT +int bacnet_log_record_decode( + const uint8_t *apdu, size_t apdu_len, BACNET_LOG_RECORD *value); + +BACNET_STACK_EXPORT +int bacnet_log_record_datum32_decode( + const uint8_t *apdu, + size_t apdu_size, + uint8_t tag_data_type, + uint32_t len_value_type, + BACNET_LOG_RECORD *value); +BACNET_STACK_EXPORT +int bacnet_log_record_encode( + uint8_t *apdu, size_t apdu_size, const BACNET_LOG_RECORD *value); + +BACNET_STACK_EXPORT +bool bacnet_log_record_datum_from_ascii( + BACNET_LOG_RECORD *value, const char *argv); +BACNET_STACK_EXPORT +bool bacnet_log_record_copy( + BACNET_LOG_RECORD *dest, const BACNET_LOG_RECORD *src); +BACNET_STACK_EXPORT +bool bacnet_log_record_same( + const BACNET_LOG_RECORD *value1, const BACNET_LOG_RECORD *value2); + +BACNET_STACK_EXPORT +void bacnet_log_record_datum_bitstring_set( + struct bacnet_log_datum_bitstring *bit_string, + uint8_t bit_number, + bool value); +BACNET_STACK_EXPORT +bool bacnet_log_record_datum_bitstring_same( + const struct bacnet_log_datum_bitstring *value1, + const struct bacnet_log_datum_bitstring *value2); + +BACNET_STACK_EXPORT +bool bacnet_log_record_status_flags_bit( + uint8_t status_flags, uint8_t bit_number); +BACNET_STACK_EXPORT +void bacnet_log_record_status_flags_bit_set( + uint8_t *status_flags, uint8_t bit_number, bool value); + +BACNET_STACK_EXPORT +void bacnet_log_record_link_array(BACNET_LOG_RECORD *array, size_t size); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/src/bacnet/bactext.c b/src/bacnet/bactext.c index 7cf88077..5a450232 100644 --- a/src/bacnet/bactext.c +++ b/src/bacnet/bactext.c @@ -2148,3 +2148,25 @@ const char *bactext_shed_level_type_name(unsigned index) return indtext_by_index_default( bacnet_shed_level_type_names, index, ASHRAE_Reserved_String); } + +/* note: different than DaysOfWeek bit string where 0=monday */ +INDTEXT_DATA bacnet_log_datum_names[] = { + { BACNET_LOG_DATUM_STATUS, "status" }, + { BACNET_LOG_DATUM_BOOLEAN, "boolean" }, + { BACNET_LOG_DATUM_REAL, "real" }, + { BACNET_LOG_DATUM_ENUMERATED, "enumerated" }, + { BACNET_LOG_DATUM_UNSIGNED, "unsigned" }, + { BACNET_LOG_DATUM_SIGNED, "signed" }, + { BACNET_LOG_DATUM_BITSTRING, "bitstring" }, + { BACNET_LOG_DATUM_NULL, "null" }, + { BACNET_LOG_DATUM_FAILURE, "failure" }, + { BACNET_LOG_DATUM_TIME_CHANGE, "time-change" }, + { BACNET_LOG_DATUM_ANY, "any" }, + { 0, NULL } +}; + +const char *bactext_log_datum_name(unsigned index) +{ + return indtext_by_index_default( + bacnet_log_datum_names, index, ASHRAE_Reserved_String); +} diff --git a/src/bacnet/bactext.h b/src/bacnet/bactext.h index 59802ac8..f457ca01 100644 --- a/src/bacnet/bactext.h +++ b/src/bacnet/bactext.h @@ -155,6 +155,9 @@ const char *bactext_shed_state_name(unsigned index); BACNET_STACK_EXPORT const char *bactext_shed_level_type_name(unsigned index); +BACNET_STACK_EXPORT +const char *bactext_log_datum_name(unsigned index); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/bacnet/basic/service/h_rr_a.c b/src/bacnet/basic/service/h_rr_a.c index 95404308..e729829d 100644 --- a/src/bacnet/basic/service/h_rr_a.c +++ b/src/bacnet/basic/service/h_rr_a.c @@ -18,6 +18,7 @@ #include "bacnet/basic/object/device.h" #include "bacnet/basic/services.h" #include "bacnet/basic/tsm/tsm.h" +#include "bacnet/basic/sys/debug.h" /** @file h_rr_a.c Handles Read Range Acknowledgments. */ @@ -32,24 +33,49 @@ static void PrintReadRangeData(BACNET_READ_RANGE_DATA *data) uint8_t *application_data; int application_data_len; bool first_value = true; -#if PRINT_ENABLED bool print_brace = false; -#endif if (data) { + debug_printf_stdout( + "%s #%lu\r\n", bactext_object_type_name(data->object_type), + (unsigned long)data->object_instance); + debug_printf_stdout("{\r\n"); + if ((data->object_property < 512) || + (data->object_property > 4194303)) { + /* Enumerated values 0-511 and 4194304+ are reserved + for definition by ASHRAE.*/ + debug_printf_stdout( + " %s", bactext_property_name(data->object_property)); + } else { + /* Enumerated values 512-4194303 may be used + by others subject to the procedures and + constraints described in Clause 23. */ + debug_printf_stdout( + " proprietary %u", (unsigned)data->object_property); + } + if (data->array_index == BACNET_ARRAY_ALL) { + debug_printf_stdout(": "); + } else { + debug_printf_stdout("[%lu]: ", (unsigned long)data->array_index); + } application_data = data->application_data; application_data_len = data->application_data_len; - /* FIXME: what if application_data_len is bigger than 255? */ - /* value? need to loop until all of the len is gone... */ + /* loop until all of the len is gone... */ for (;;) { - len = bacapp_decode_application_data( - application_data, (uint8_t)application_data_len, &value); + len = bacapp_decode_known_array_property( + application_data, (uint8_t)application_data_len, &value, + data->object_type, data->object_property, data->array_index); + if (len < 0) { + /* error decoding */ + break; + } + if (!first_value) { + debug_printf_stdout(" "); + } if (first_value && (len < application_data_len)) { first_value = false; -#if PRINT_ENABLED - fprintf(stdout, "{"); + debug_printf_stdout("{"); print_brace = true; -#endif } #ifdef BACAPP_PRINT_ENABLED object_value.object_type = data->object_type; @@ -64,9 +90,7 @@ static void PrintReadRangeData(BACNET_READ_RANGE_DATA *data) application_data += len; application_data_len -= len; /* there's more! */ -#if PRINT_ENABLED - fprintf(stdout, ","); -#endif + debug_printf_stdout(",\r\n"); } else { break; } @@ -74,12 +98,10 @@ static void PrintReadRangeData(BACNET_READ_RANGE_DATA *data) break; } } -#if PRINT_ENABLED if (print_brace) { - fprintf(stdout, "}"); + debug_printf_stdout("}"); } - fprintf(stdout, "\r\n"); -#endif + debug_printf_stdout("\r\n}\r\n"); } } @@ -95,12 +117,11 @@ void handler_read_range_ack( (void)src; (void)service_data; /* we could use these... */ len = rr_ack_decode_service_request(service_request, service_len, &data); - -#if PRINT_ENABLED - fprintf(stderr, "Received ReadRange Ack!\n"); -#endif - if (len > 0) { PrintReadRangeData(&data); + } else { +#if PRINT_ENABLED + fprintf(stderr, "Received ReadRange Ack!\n"); +#endif } } diff --git a/src/bacnet/channel_value.c b/src/bacnet/channel_value.c index f306612f..75773655 100644 --- a/src/bacnet/channel_value.c +++ b/src/bacnet/channel_value.c @@ -1,6 +1,6 @@ /** * @file - * @brief BACnet single precision REAL encode and decode functions + * @brief BACnet Channel Value data type encoding and decoding * @author Steve Karg * @date 2004 * @copyright SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0 diff --git a/src/bacnet/channel_value.h b/src/bacnet/channel_value.h index f82e1565..1bab0504 100644 --- a/src/bacnet/channel_value.h +++ b/src/bacnet/channel_value.h @@ -1,6 +1,6 @@ /** * @file - * @brief BACnet single precision REAL encode and decode functions + * @brief BACnet Channel Value data type * @author Steve Karg * @date 2012 * @copyright SPDX-License-Identifier: MIT @@ -14,7 +14,6 @@ /* BACnet Stack defines - first */ #include "bacnet/bacdef.h" #include "bacnet/lighting.h" -#include "bacnet/lighting.h" /* BACNET_CHANNEL_VALUE decodes WriteProperty service requests Choose the datatypes that your application supports */ diff --git a/src/bacnet/config.h b/src/bacnet/config.h index 8cf3f215..052d4706 100644 --- a/src/bacnet/config.h +++ b/src/bacnet/config.h @@ -234,6 +234,7 @@ defined(BACAPP_SHED_LEVEL) || \ defined(BACAPP_ACCESS_RULE) || \ defined(BACAPP_CHANNEL_VALUE) || \ + defined(BACAPP_LOG_RECORD) || \ defined(BACAPP_SECURE_CONNECT) || \ defined(BACAPP_TYPES_EXTRA)) #define BACAPP_ALL @@ -283,6 +284,7 @@ #define BACAPP_SHED_LEVEL #define BACAPP_ACCESS_RULE #define BACAPP_CHANNEL_VALUE +#define BACAPP_LOG_RECORD #define BACAPP_SECURE_CONNECT #endif @@ -308,7 +310,8 @@ defined(BACAPP_SCALE) || \ defined(BACAPP_SHED_LEVEL) || \ defined(BACAPP_ACCESS_RULE) || \ - defined(BACAPP_CHANNEL_VALUE) + defined(BACAPP_CHANNEL_VALUE) || \ + defined(BACAPP_LOG_RECORD) #define BACAPP_COMPLEX_TYPES #endif /* clang-format on */ diff --git a/src/bacnet/readrange.c b/src/bacnet/readrange.c index c16288cc..a806f8ff 100644 --- a/src/bacnet/readrange.c +++ b/src/bacnet/readrange.c @@ -391,15 +391,16 @@ int rr_decode_service_request( /* * ReadRange-ACK ::= SEQUENCE { - * objectIdentifier [0] BACnetObjectIdentifier, - * propertyIdentifier [1] BACnetPropertyIdentifier, - * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with - * array datatype resultFlags [3] BACnetResultFlags, itemCount [4] - * Unsigned, itemData [5] SEQUENCE OF ABSTRACT-SYNTAX.&TYPE, - * firstSequenceNumber [6] Unsigned32 OPTIONAL -- used only if 'Item - * Count' > 0 and the request was either of - * -- type 'By Sequence - * Number' or 'By Time' + * objectIdentifier [0] BACnetObjectIdentifier, + * propertyIdentifier [1] BACnetPropertyIdentifier, + * propertyArrayIndex [2] Unsigned OPTIONAL, + * -- used only with array datatype + * resultFlags [3] BACnetResultFlags, + * itemCount [4] Unsigned, + * itemData [5] SEQUENCE OF ABSTRACT-SYNTAX.&TYPE, + * firstSequenceNumber [6] Unsigned32 OPTIONAL + * -- used only if 'Item Count' > 0 and + * -- the request was either of type 'By Sequence Number' or 'By Time' * } */ @@ -592,7 +593,7 @@ int rr_ack_decode_service_request( return -1; } if (len < apdu_len) { /* Still something left to look at? */ - /* Tag 6: Item count */ + /* Tag 6: FirstSequence */ len += decode_tag_number_and_value( &apdu[len], &tag_number, &len_value_type); if (tag_number != 6) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ac3ba45a..a9dae6dc 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -81,6 +81,7 @@ list(APPEND testdirs bacnet/bacdest bacnet/bacerror bacnet/bacint + bacnet/baclog bacnet/bacpropstates bacnet/bacreal bacnet/bacstr diff --git a/test/bacnet/access_rule/CMakeLists.txt b/test/bacnet/access_rule/CMakeLists.txt index 90635857..0eaa84b9 100644 --- a/test/bacnet/access_rule/CMakeLists.txt +++ b/test/bacnet/access_rule/CMakeLists.txt @@ -45,6 +45,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdcode.c ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/bacapp/CMakeLists.txt b/test/bacnet/bacapp/CMakeLists.txt index 4d2e16d7..18e0dc64 100644 --- a/test/bacnet/bacapp/CMakeLists.txt +++ b/test/bacnet/bacapp/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdcode.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/bacdest/CMakeLists.txt b/test/bacnet/bacdest/CMakeLists.txt index 7c3f14f5..fbd22411 100644 --- a/test/bacnet/bacdest/CMakeLists.txt +++ b/test/bacnet/bacdest/CMakeLists.txt @@ -44,6 +44,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/bacdevobjpropref/CMakeLists.txt b/test/bacnet/bacdevobjpropref/CMakeLists.txt index f8b6207b..97523efd 100644 --- a/test/bacnet/bacdevobjpropref/CMakeLists.txt +++ b/test/bacnet/bacdevobjpropref/CMakeLists.txt @@ -46,6 +46,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdcode.c ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/baclog/CMakeLists.txt b/test/bacnet/baclog/CMakeLists.txt new file mode 100644 index 00000000..8398eab9 --- /dev/null +++ b/test/bacnet/baclog/CMakeLists.txt @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.10 FATAL_ERROR) + +get_filename_component(basename ${CMAKE_CURRENT_SOURCE_DIR} NAME) +project(test_${basename} + VERSION 1.0.0 + LANGUAGES C) + + +string(REGEX REPLACE + "/test/bacnet/[a-zA-Z_/-]*$" + "/src" + SRC_DIR + ${CMAKE_CURRENT_SOURCE_DIR}) +string(REGEX REPLACE + "/test/bacnet/[a-zA-Z_/-]*$" + "/test" + TST_DIR + ${CMAKE_CURRENT_SOURCE_DIR}) +set(ZTST_DIR "${TST_DIR}/ztest/src") + +add_compile_definitions( + BIG_ENDIAN=0 + CONFIG_ZTEST=1 + BACAPP_MINIMAL=1 + ) + +include_directories( + ${SRC_DIR} + ${TST_DIR}/ztest/include + ) + +add_executable(${PROJECT_NAME} + # File(s) under test + ${SRC_DIR}/bacnet/baclog.c + # Support files and stubs (pathname alphabetical) + ${SRC_DIR}/bacnet/access_rule.c + ${SRC_DIR}/bacnet/bacaction.c + ${SRC_DIR}/bacnet/bacaddr.c + ${SRC_DIR}/bacnet/bacapp.c + ${SRC_DIR}/bacnet/bacdcode.c + ${SRC_DIR}/bacnet/bacdest.c + ${SRC_DIR}/bacnet/bacdevobjpropref.c + ${SRC_DIR}/bacnet/bacerror.c + ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c + ${SRC_DIR}/bacnet/bacreal.c + ${SRC_DIR}/bacnet/bacstr.c + ${SRC_DIR}/bacnet/bactext.c + ${SRC_DIR}/bacnet/basic/sys/bigend.c + ${SRC_DIR}/bacnet/datetime.c + ${SRC_DIR}/bacnet/basic/sys/days.c + ${SRC_DIR}/bacnet/indtext.c + ${SRC_DIR}/bacnet/hostnport.c + ${SRC_DIR}/bacnet/lighting.c + ${SRC_DIR}/bacnet/timestamp.c + ${SRC_DIR}/bacnet/timesync.c + ${SRC_DIR}/bacnet/weeklyschedule.c + ${SRC_DIR}/bacnet/bactimevalue.c + ${SRC_DIR}/bacnet/dailyschedule.c + ${SRC_DIR}/bacnet/calendar_entry.c + ${SRC_DIR}/bacnet/special_event.c + ${SRC_DIR}/bacnet/channel_value.c + ${SRC_DIR}/bacnet/secure_connect.c + # Test and test library files + ./src/main.c + ${ZTST_DIR}/ztest_mock.c + ${ZTST_DIR}/ztest.c + ) diff --git a/test/bacnet/baclog/src/main.c b/test/bacnet/baclog/src/main.c new file mode 100644 index 00000000..e862c998 --- /dev/null +++ b/test/bacnet/baclog/src/main.c @@ -0,0 +1,140 @@ +/** + * @file + * @brief Unit test for for BACnetAuditNotification and BACnetAuditLogRecord + * @author Steve Karg + * @date November 2024 + * @copyright SPDX-License-Identifier: MIT + */ +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @addtogroup bacnet_tests + * @{ + */ + +static void test_bacnet_log_record_datum(BACNET_LOG_RECORD *value) +{ + uint8_t apdu[MAX_APDU] = { 0 }; + BACNET_LOG_RECORD test_value = { 0 }; + int apdu_len = 0, null_len = 0, test_len = 0; + + value->status_flags = 0; + null_len = bacnet_log_record_encode(NULL, sizeof(apdu), value); + apdu_len = bacnet_log_record_encode(apdu, sizeof(apdu), value); + zassert_equal(apdu_len, null_len, NULL); + null_len = bacnet_log_record_decode(apdu, apdu_len, NULL); + zassert_equal(apdu_len, null_len, NULL); + test_len = bacnet_log_record_decode(apdu, apdu_len, &test_value); + zassert_equal(apdu_len, test_len, "datum=%u", value->tag); + zassert_true(bacnet_log_record_same(value, &test_value), NULL); + + value->status_flags = 0x0F; + null_len = bacnet_log_record_encode(NULL, sizeof(apdu), value); + apdu_len = bacnet_log_record_encode(apdu, sizeof(apdu), value); + zassert_equal(apdu_len, null_len, NULL); + null_len = bacnet_log_record_decode(apdu, apdu_len, NULL); + zassert_equal(apdu_len, null_len, NULL); + test_len = bacnet_log_record_decode(apdu, apdu_len, &test_value); + zassert_equal(apdu_len, test_len, NULL); + zassert_true(bacnet_log_record_same(value, &test_value), NULL); + + BIT_SET(value->status_flags, 7); + null_len = bacnet_log_record_encode(NULL, sizeof(apdu), value); + apdu_len = bacnet_log_record_encode(apdu, sizeof(apdu), value); + zassert_equal(apdu_len, null_len, NULL); + null_len = bacnet_log_record_decode(apdu, apdu_len, NULL); + zassert_equal(apdu_len, null_len, NULL); + test_len = bacnet_log_record_decode(apdu, apdu_len, &test_value); + zassert_equal(apdu_len, test_len, NULL); + zassert_true(bacnet_log_record_same(value, &test_value), NULL); + + /* decoding, some negative tests */ + test_len = bacnet_log_record_decode(NULL, apdu_len, &test_value); + zassert_equal(test_len, BACNET_STATUS_ERROR, NULL); + test_len = bacnet_log_record_decode(apdu, 0, &test_value); + zassert_equal(test_len, BACNET_STATUS_ERROR, NULL); +} + +uint8_t Test_APDU[MAX_APDU]; +#if defined(CONFIG_ZTEST_NEW_API) +ZTEST(bacnet_log_tests, test_bacnet_log_record) +#else +static void test_bacnet_log_record(void) +#endif +{ + BACNET_LOG_RECORD value = { 0 }, test_value = { 0 }; + bool status = false; + + /* common */ + datetime_init_ascii(&value.timestamp, "2021/12/31-23:59:59.99"); + + /* value type = null */ + status = bacnet_log_record_datum_from_ascii(&value, "null"); + zassert_true(status, NULL); + zassert_equal(value.tag, BACNET_LOG_DATUM_NULL, NULL); + test_bacnet_log_record_datum(&value); + + /* value type = boolean */ + status = bacnet_log_record_datum_from_ascii(&value, "true"); + zassert_true(status, NULL); + zassert_equal(value.tag, BACNET_LOG_DATUM_BOOLEAN, NULL); + zassert_equal(value.log_datum.boolean_value, true, NULL); + test_bacnet_log_record_datum(&value); + + /* value type = unsigned */ + status = bacnet_log_record_datum_from_ascii(&value, "1234"); + zassert_true(status, NULL); + zassert_equal(value.tag, BACNET_LOG_DATUM_UNSIGNED, NULL); + zassert_equal(value.log_datum.unsigned_value, 1234, NULL); + test_bacnet_log_record_datum(&value); + + /* value type = signed */ + status = bacnet_log_record_datum_from_ascii(&value, "-1234"); + zassert_true(status, NULL); + zassert_equal(value.tag, BACNET_LOG_DATUM_SIGNED, NULL); + zassert_equal(value.log_datum.integer_value, -1234, NULL); + test_bacnet_log_record_datum(&value); + + /* value type = REAL */ + status = bacnet_log_record_datum_from_ascii(&value, "3.14159"); + zassert_true(status, NULL); + zassert_equal(value.tag, BACNET_LOG_DATUM_REAL, NULL); + status = islessgreater(value.log_datum.real_value, 3.14159f); + zassert_false(status, NULL); + test_bacnet_log_record_datum(&value); + + /* value type = ENUMERATED */ + value.tag = BACNET_LOG_DATUM_ENUMERATED; + value.log_datum.enumerated_value = 1234; + test_bacnet_log_record_datum(&value); + + status = bacnet_log_record_same(&value, NULL); + zassert_false(status, NULL); + status = bacnet_log_record_same(NULL, &value); + zassert_false(status, NULL); + value.tag = 255; + test_value.tag = 255; + status = bacnet_log_record_same(&value, &test_value); + zassert_false(status, NULL); +} +/** + * @} + */ + +#if defined(CONFIG_ZTEST_NEW_API) +ZTEST_SUITE(bacnet_log_tests, NULL, NULL, NULL, NULL, NULL); +#else +void test_main(void) +{ + ztest_test_suite(bacnet_log_tests, ztest_unit_test(test_bacnet_log_record)); + + ztest_run_test_suite(bacnet_log_tests); +} +#endif diff --git a/test/bacnet/bactimevalue/CMakeLists.txt b/test/bacnet/bactimevalue/CMakeLists.txt index 630f027c..4be4d8e9 100644 --- a/test/bacnet/bactimevalue/CMakeLists.txt +++ b/test/bacnet/bactimevalue/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdcode.c ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c diff --git a/test/bacnet/basic/binding/address/CMakeLists.txt b/test/bacnet/basic/binding/address/CMakeLists.txt index a509af4c..5c449677 100644 --- a/test/bacnet/basic/binding/address/CMakeLists.txt +++ b/test/bacnet/basic/binding/address/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/acc/CMakeLists.txt b/test/bacnet/basic/object/acc/CMakeLists.txt index 4ca28496..9d8b48ae 100644 --- a/test/bacnet/basic/object/acc/CMakeLists.txt +++ b/test/bacnet/basic/object/acc/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/access_credential/CMakeLists.txt b/test/bacnet/basic/object/access_credential/CMakeLists.txt index 3b76b44e..ed90e11b 100644 --- a/test/bacnet/basic/object/access_credential/CMakeLists.txt +++ b/test/bacnet/basic/object/access_credential/CMakeLists.txt @@ -44,6 +44,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/access_door/CMakeLists.txt b/test/bacnet/basic/object/access_door/CMakeLists.txt index b63d0866..1770cc06 100644 --- a/test/bacnet/basic/object/access_door/CMakeLists.txt +++ b/test/bacnet/basic/object/access_door/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/access_point/CMakeLists.txt b/test/bacnet/basic/object/access_point/CMakeLists.txt index 7934f81e..53e0e15e 100644 --- a/test/bacnet/basic/object/access_point/CMakeLists.txt +++ b/test/bacnet/basic/object/access_point/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/access_rights/CMakeLists.txt b/test/bacnet/basic/object/access_rights/CMakeLists.txt index 08d25c40..f181564f 100644 --- a/test/bacnet/basic/object/access_rights/CMakeLists.txt +++ b/test/bacnet/basic/object/access_rights/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/access_user/CMakeLists.txt b/test/bacnet/basic/object/access_user/CMakeLists.txt index f2982c5c..e0eeb1c3 100644 --- a/test/bacnet/basic/object/access_user/CMakeLists.txt +++ b/test/bacnet/basic/object/access_user/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/access_zone/CMakeLists.txt b/test/bacnet/basic/object/access_zone/CMakeLists.txt index 3a570e20..a9ca5c11 100644 --- a/test/bacnet/basic/object/access_zone/CMakeLists.txt +++ b/test/bacnet/basic/object/access_zone/CMakeLists.txt @@ -44,6 +44,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/ai/CMakeLists.txt b/test/bacnet/basic/object/ai/CMakeLists.txt index 2ce7b6af..4b3c0e76 100644 --- a/test/bacnet/basic/object/ai/CMakeLists.txt +++ b/test/bacnet/basic/object/ai/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdcode.c ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/ao/CMakeLists.txt b/test/bacnet/basic/object/ao/CMakeLists.txt index 1f208221..fdacc383 100644 --- a/test/bacnet/basic/object/ao/CMakeLists.txt +++ b/test/bacnet/basic/object/ao/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/av/CMakeLists.txt b/test/bacnet/basic/object/av/CMakeLists.txt index 9f134ec5..f2df11e7 100644 --- a/test/bacnet/basic/object/av/CMakeLists.txt +++ b/test/bacnet/basic/object/av/CMakeLists.txt @@ -44,6 +44,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/bacfile/CMakeLists.txt b/test/bacnet/basic/object/bacfile/CMakeLists.txt index 4b0a12d5..8071bab1 100644 --- a/test/bacnet/basic/object/bacfile/CMakeLists.txt +++ b/test/bacnet/basic/object/bacfile/CMakeLists.txt @@ -46,6 +46,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/bi/CMakeLists.txt b/test/bacnet/basic/object/bi/CMakeLists.txt index 47f9f1d2..162df733 100644 --- a/test/bacnet/basic/object/bi/CMakeLists.txt +++ b/test/bacnet/basic/object/bi/CMakeLists.txt @@ -45,6 +45,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/bitstring_value/CMakeLists.txt b/test/bacnet/basic/object/bitstring_value/CMakeLists.txt index 9163cf44..d6dedb10 100644 --- a/test/bacnet/basic/object/bitstring_value/CMakeLists.txt +++ b/test/bacnet/basic/object/bitstring_value/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/blo/CMakeLists.txt b/test/bacnet/basic/object/blo/CMakeLists.txt index 0e506efb..bf2872a9 100644 --- a/test/bacnet/basic/object/blo/CMakeLists.txt +++ b/test/bacnet/basic/object/blo/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/bo/CMakeLists.txt b/test/bacnet/basic/object/bo/CMakeLists.txt index 588ce6dd..25bb39d2 100644 --- a/test/bacnet/basic/object/bo/CMakeLists.txt +++ b/test/bacnet/basic/object/bo/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/bv/CMakeLists.txt b/test/bacnet/basic/object/bv/CMakeLists.txt index 661c3854..36c5ebba 100644 --- a/test/bacnet/basic/object/bv/CMakeLists.txt +++ b/test/bacnet/basic/object/bv/CMakeLists.txt @@ -45,6 +45,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/calendar/CMakeLists.txt b/test/bacnet/basic/object/calendar/CMakeLists.txt index 49a7e204..48c3e199 100644 --- a/test/bacnet/basic/object/calendar/CMakeLists.txt +++ b/test/bacnet/basic/object/calendar/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/channel/CMakeLists.txt b/test/bacnet/basic/object/channel/CMakeLists.txt index 136c149a..6ff55e40 100644 --- a/test/bacnet/basic/object/channel/CMakeLists.txt +++ b/test/bacnet/basic/object/channel/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/color_object/CMakeLists.txt b/test/bacnet/basic/object/color_object/CMakeLists.txt index 7859b4bb..ac393ac0 100644 --- a/test/bacnet/basic/object/color_object/CMakeLists.txt +++ b/test/bacnet/basic/object/color_object/CMakeLists.txt @@ -41,6 +41,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdcode.c ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacint.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c diff --git a/test/bacnet/basic/object/color_temperature/CMakeLists.txt b/test/bacnet/basic/object/color_temperature/CMakeLists.txt index 06e6dc40..ecf268cd 100644 --- a/test/bacnet/basic/object/color_temperature/CMakeLists.txt +++ b/test/bacnet/basic/object/color_temperature/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/command/CMakeLists.txt b/test/bacnet/basic/object/command/CMakeLists.txt index 0a36a933..7bfa47b4 100644 --- a/test/bacnet/basic/object/command/CMakeLists.txt +++ b/test/bacnet/basic/object/command/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/credential_data_input/CMakeLists.txt b/test/bacnet/basic/object/credential_data_input/CMakeLists.txt index 386dd01d..03ceb9a1 100644 --- a/test/bacnet/basic/object/credential_data_input/CMakeLists.txt +++ b/test/bacnet/basic/object/credential_data_input/CMakeLists.txt @@ -45,6 +45,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/csv/CMakeLists.txt b/test/bacnet/basic/object/csv/CMakeLists.txt index 8e32aa60..c636b720 100644 --- a/test/bacnet/basic/object/csv/CMakeLists.txt +++ b/test/bacnet/basic/object/csv/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/device/CMakeLists.txt b/test/bacnet/basic/object/device/CMakeLists.txt index d5d5003e..ce21173d 100644 --- a/test/bacnet/basic/object/device/CMakeLists.txt +++ b/test/bacnet/basic/object/device/CMakeLists.txt @@ -44,6 +44,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/iv/CMakeLists.txt b/test/bacnet/basic/object/iv/CMakeLists.txt index a4e14828..1af78de9 100644 --- a/test/bacnet/basic/object/iv/CMakeLists.txt +++ b/test/bacnet/basic/object/iv/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/lc/CMakeLists.txt b/test/bacnet/basic/object/lc/CMakeLists.txt index 8d10b2a4..f83246a5 100644 --- a/test/bacnet/basic/object/lc/CMakeLists.txt +++ b/test/bacnet/basic/object/lc/CMakeLists.txt @@ -47,6 +47,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/lo/CMakeLists.txt b/test/bacnet/basic/object/lo/CMakeLists.txt index bf5c7cfe..2d65a162 100644 --- a/test/bacnet/basic/object/lo/CMakeLists.txt +++ b/test/bacnet/basic/object/lo/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/lsp/CMakeLists.txt b/test/bacnet/basic/object/lsp/CMakeLists.txt index 804882ac..a9627d2f 100644 --- a/test/bacnet/basic/object/lsp/CMakeLists.txt +++ b/test/bacnet/basic/object/lsp/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/lsz/CMakeLists.txt b/test/bacnet/basic/object/lsz/CMakeLists.txt index de3727af..56b7f41e 100644 --- a/test/bacnet/basic/object/lsz/CMakeLists.txt +++ b/test/bacnet/basic/object/lsz/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/ms-input/CMakeLists.txt b/test/bacnet/basic/object/ms-input/CMakeLists.txt index ecda1ceb..beb0b686 100644 --- a/test/bacnet/basic/object/ms-input/CMakeLists.txt +++ b/test/bacnet/basic/object/ms-input/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/mso/CMakeLists.txt b/test/bacnet/basic/object/mso/CMakeLists.txt index f3475e31..2d94fa04 100644 --- a/test/bacnet/basic/object/mso/CMakeLists.txt +++ b/test/bacnet/basic/object/mso/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/msv/CMakeLists.txt b/test/bacnet/basic/object/msv/CMakeLists.txt index b485b1f2..09def1c7 100644 --- a/test/bacnet/basic/object/msv/CMakeLists.txt +++ b/test/bacnet/basic/object/msv/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/nc/CMakeLists.txt b/test/bacnet/basic/object/nc/CMakeLists.txt index b971cf0e..9381cce6 100644 --- a/test/bacnet/basic/object/nc/CMakeLists.txt +++ b/test/bacnet/basic/object/nc/CMakeLists.txt @@ -44,6 +44,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/netport/CMakeLists.txt b/test/bacnet/basic/object/netport/CMakeLists.txt index f65fcb40..31443627 100644 --- a/test/bacnet/basic/object/netport/CMakeLists.txt +++ b/test/bacnet/basic/object/netport/CMakeLists.txt @@ -66,6 +66,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c @@ -118,6 +119,7 @@ elseif(APPLE) ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/osv/CMakeLists.txt b/test/bacnet/basic/object/osv/CMakeLists.txt index 97485b41..20ec6946 100644 --- a/test/bacnet/basic/object/osv/CMakeLists.txt +++ b/test/bacnet/basic/object/osv/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/piv/CMakeLists.txt b/test/bacnet/basic/object/piv/CMakeLists.txt index 5aed0bec..c6bb6d09 100644 --- a/test/bacnet/basic/object/piv/CMakeLists.txt +++ b/test/bacnet/basic/object/piv/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/program/CMakeLists.txt b/test/bacnet/basic/object/program/CMakeLists.txt index f471b3ea..7290df8c 100644 --- a/test/bacnet/basic/object/program/CMakeLists.txt +++ b/test/bacnet/basic/object/program/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/schedule/CMakeLists.txt b/test/bacnet/basic/object/schedule/CMakeLists.txt index 67abf42f..5ffbbc21 100644 --- a/test/bacnet/basic/object/schedule/CMakeLists.txt +++ b/test/bacnet/basic/object/schedule/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/structured_view/CMakeLists.txt b/test/bacnet/basic/object/structured_view/CMakeLists.txt index 4a8b551d..7ef0e3a0 100644 --- a/test/bacnet/basic/object/structured_view/CMakeLists.txt +++ b/test/bacnet/basic/object/structured_view/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/time_value/CMakeLists.txt b/test/bacnet/basic/object/time_value/CMakeLists.txt index 44a11f00..eeb0cf2f 100644 --- a/test/bacnet/basic/object/time_value/CMakeLists.txt +++ b/test/bacnet/basic/object/time_value/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/basic/object/trendlog/CMakeLists.txt b/test/bacnet/basic/object/trendlog/CMakeLists.txt index 4be8a788..6505d4cd 100644 --- a/test/bacnet/basic/object/trendlog/CMakeLists.txt +++ b/test/bacnet/basic/object/trendlog/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/cov/CMakeLists.txt b/test/bacnet/cov/CMakeLists.txt index 0c2606f0..8fb77c88 100644 --- a/test/bacnet/cov/CMakeLists.txt +++ b/test/bacnet/cov/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/create_object/CMakeLists.txt b/test/bacnet/create_object/CMakeLists.txt index 43d5d6a1..13dc80a8 100644 --- a/test/bacnet/create_object/CMakeLists.txt +++ b/test/bacnet/create_object/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/datalink/bsc-datalink/CMakeLists.txt b/test/bacnet/datalink/bsc-datalink/CMakeLists.txt index 21bfc97a..9f98ea2e 100644 --- a/test/bacnet/datalink/bsc-datalink/CMakeLists.txt +++ b/test/bacnet/datalink/bsc-datalink/CMakeLists.txt @@ -177,6 +177,7 @@ target_sources(${PROJECT_NAME} PRIVATE ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/datalink/bsc-node/CMakeLists.txt b/test/bacnet/datalink/bsc-node/CMakeLists.txt index 8e97a7cf..6494ded0 100644 --- a/test/bacnet/datalink/bsc-node/CMakeLists.txt +++ b/test/bacnet/datalink/bsc-node/CMakeLists.txt @@ -168,6 +168,7 @@ target_sources(${PROJECT_NAME} PRIVATE ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/datalink/bsc-socket/CMakeLists.txt b/test/bacnet/datalink/bsc-socket/CMakeLists.txt index 9d2d065b..6a373fda 100644 --- a/test/bacnet/datalink/bsc-socket/CMakeLists.txt +++ b/test/bacnet/datalink/bsc-socket/CMakeLists.txt @@ -166,6 +166,7 @@ target_sources(${PROJECT_NAME} PRIVATE ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/datalink/hub-sc/CMakeLists.txt b/test/bacnet/datalink/hub-sc/CMakeLists.txt index f8ea4956..2f763e0a 100644 --- a/test/bacnet/datalink/hub-sc/CMakeLists.txt +++ b/test/bacnet/datalink/hub-sc/CMakeLists.txt @@ -171,6 +171,7 @@ target_sources(${PROJECT_NAME} PRIVATE ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/delete_object/CMakeLists.txt b/test/bacnet/delete_object/CMakeLists.txt index 4e704c0e..0233cac1 100644 --- a/test/bacnet/delete_object/CMakeLists.txt +++ b/test/bacnet/delete_object/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/event/CMakeLists.txt b/test/bacnet/event/CMakeLists.txt index 08afbf57..ba49b2c5 100644 --- a/test/bacnet/event/CMakeLists.txt +++ b/test/bacnet/event/CMakeLists.txt @@ -41,6 +41,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bacpropstates.c diff --git a/test/bacnet/getalarm/CMakeLists.txt b/test/bacnet/getalarm/CMakeLists.txt index 2e5f0140..94ae8e73 100644 --- a/test/bacnet/getalarm/CMakeLists.txt +++ b/test/bacnet/getalarm/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/getevent/CMakeLists.txt b/test/bacnet/getevent/CMakeLists.txt index cfc6d5e6..0494218f 100644 --- a/test/bacnet/getevent/CMakeLists.txt +++ b/test/bacnet/getevent/CMakeLists.txt @@ -42,6 +42,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/hostnport/CMakeLists.txt b/test/bacnet/hostnport/CMakeLists.txt index 1172d907..ab73c882 100644 --- a/test/bacnet/hostnport/CMakeLists.txt +++ b/test/bacnet/hostnport/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/list_element/CMakeLists.txt b/test/bacnet/list_element/CMakeLists.txt index 10c2f6ad..ad4cd459 100644 --- a/test/bacnet/list_element/CMakeLists.txt +++ b/test/bacnet/list_element/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/lso/CMakeLists.txt b/test/bacnet/lso/CMakeLists.txt index b31eab45..3526b51c 100644 --- a/test/bacnet/lso/CMakeLists.txt +++ b/test/bacnet/lso/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/ptransfer/CMakeLists.txt b/test/bacnet/ptransfer/CMakeLists.txt index 272b825a..cda3351a 100644 --- a/test/bacnet/ptransfer/CMakeLists.txt +++ b/test/bacnet/ptransfer/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/rpm/CMakeLists.txt b/test/bacnet/rpm/CMakeLists.txt index adc4ef5f..25155dc9 100644 --- a/test/bacnet/rpm/CMakeLists.txt +++ b/test/bacnet/rpm/CMakeLists.txt @@ -44,6 +44,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/secure_connect/CMakeLists.txt b/test/bacnet/secure_connect/CMakeLists.txt index c20ad668..6441a7f9 100644 --- a/test/bacnet/secure_connect/CMakeLists.txt +++ b/test/bacnet/secure_connect/CMakeLists.txt @@ -41,6 +41,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bactimevalue.c ${SRC_DIR}/bacnet/bacstr.c diff --git a/test/bacnet/specialevent/CMakeLists.txt b/test/bacnet/specialevent/CMakeLists.txt index fcbc5a81..82cba2aa 100644 --- a/test/bacnet/specialevent/CMakeLists.txt +++ b/test/bacnet/specialevent/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/timesync/CMakeLists.txt b/test/bacnet/timesync/CMakeLists.txt index bb573965..479a1bb5 100644 --- a/test/bacnet/timesync/CMakeLists.txt +++ b/test/bacnet/timesync/CMakeLists.txt @@ -44,6 +44,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/weeklyschedule/CMakeLists.txt b/test/bacnet/weeklyschedule/CMakeLists.txt index 68a4a9cd..10b53992 100644 --- a/test/bacnet/weeklyschedule/CMakeLists.txt +++ b/test/bacnet/weeklyschedule/CMakeLists.txt @@ -45,6 +45,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/wp/CMakeLists.txt b/test/bacnet/wp/CMakeLists.txt index cc98cc80..d8058007 100644 --- a/test/bacnet/wp/CMakeLists.txt +++ b/test/bacnet/wp/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdest.c ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/wpm/CMakeLists.txt b/test/bacnet/wpm/CMakeLists.txt index 7ff19224..cf48c974 100644 --- a/test/bacnet/wpm/CMakeLists.txt +++ b/test/bacnet/wpm/CMakeLists.txt @@ -44,6 +44,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c diff --git a/test/bacnet/write_group/CMakeLists.txt b/test/bacnet/write_group/CMakeLists.txt index 1465fed5..993c59e8 100644 --- a/test/bacnet/write_group/CMakeLists.txt +++ b/test/bacnet/write_group/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacdevobjpropref.c ${SRC_DIR}/bacnet/bacerror.c ${SRC_DIR}/bacnet/bacint.c + ${SRC_DIR}/bacnet/baclog.c ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c