Secured event decoding by refactoring deprecated functions. (#1126)

* Secured event and authentication decoding by removing deprecated functions.

* Added extended, discrete-value, double-out-of-range, signed-out-of-range, unsigned-out-of-range, change-of-characterstring, change-of-status-flags, change-of-reliability, and change-of-timer event notification encode, decode, and unit testing with #ifdef disabled by default.
This commit is contained in:
Steve Karg
2025-11-05 21:41:30 -06:00
committed by GitHub
parent 4dd13cf199
commit 35f3964b5a
15 changed files with 4449 additions and 1345 deletions
+4
View File
@@ -16,6 +16,10 @@ The git repositories are hosted at the following sites:
### Security
* Secured UnconfirmedEventNotification-Request and
ConfirmedEventNotification-Request, BACnetNotificationParameters,
and BACnetAuthenticationFactor decoding by refactoring deprecated
functions and validating with unit testing. (#1126)
* Secured I-Am request encoding and decoding, and updated the example apps
and handlers to use secure version of I-Am decoder. (#1080)
* Secured GetEventInformation-Request and -ACK decoder and encoder. (#1026)
+7 -3
View File
@@ -13,6 +13,10 @@ all: apps
bsd:
$(MAKE) LEGACY=true BACNET_PORT=bsd -s -C apps all
.PHONY: linux
linux:
$(MAKE) LEGACY=true BACNET_PORT=linux -s -C apps all
.PHONY: win32
win32:
$(MAKE) LEGACY=true BACNET_PORT=win32 -s -C apps all
@@ -62,15 +66,15 @@ bsc:
.PHONY: apps
apps:
$(MAKE) -s LEGACY=true -C apps all
$(MAKE) -s -C apps all
.PHONY: lib
lib:
$(MAKE) -s LEGACY=true -C apps $@
$(MAKE) -s -C apps $@
.PHONY: library
library:
$(MAKE) -s LEGACY=true -C apps lib
$(MAKE) -s -C apps lib
CMAKE_BUILD_DIR=build
.PHONY: cmake
+106 -69
View File
@@ -22,29 +22,17 @@ int bacapp_encode_authentication_factor(
int apdu_len = 0;
len = encode_context_enumerated(apdu, 0, af->format_type);
if (len < 0) {
return -1;
} else {
apdu_len += len;
if (apdu) {
apdu += len;
}
}
len = encode_context_unsigned(apdu, 1, af->format_class);
if (len < 0) {
return -1;
} else {
apdu_len += len;
if (apdu) {
apdu += len;
}
}
len = encode_context_octet_string(apdu, 2, &af->value);
if (len < 0) {
return -1;
} else {
apdu_len += len;
}
return apdu_len;
}
@@ -77,56 +65,122 @@ int bacapp_encode_context_authentication_factor(
return apdu_len;
}
/**
* @brief Decode the BACnetAuthenticationFactor complex data
* @details
* BACnetAuthenticationFactor ::= SEQUENCE {
* format-type[0] BACnetAuthenticationFactorType,
* format-class[1] Unsigned,
* value[2] OctetString
* -- for encoding of values into this octet string see Annex P.
* }
*
* @param apdu Pointer to the buffer for decoding.
* @param apdu_size Number of valid bytes in the buffer.
* @param af Pointer to the property decoded data to be stored, or NULL for
* length of the decoded bytes.
* @return Number of bytes decoded or BACNET_STATUS_ERROR on error.
*/
int bacnet_authentication_factor_decode(
const uint8_t *apdu, unsigned apdu_size, BACNET_AUTHENTICATION_FACTOR *af)
{
int len = 0, apdu_len = 0;
uint32_t enum_value = 0;
BACNET_UNSIGNED_INTEGER unsigned_value = 0;
BACNET_OCTET_STRING *octet_string_value = NULL;
/* format-type[0] BACnetAuthenticationFactorType */
len = bacnet_enumerated_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 0, &enum_value);
if (len > 0) {
if (af) {
if (enum_value > AUTHENTICATION_FACTOR_MAX) {
enum_value = AUTHENTICATION_FACTOR_MAX;
}
af->format_type = (BACNET_AUTHENTICATION_FACTOR_TYPE)enum_value;
}
apdu_len += len;
} else {
return BACNET_STATUS_ERROR;
}
/* format-class[1] Unsigned */
len = bacnet_unsigned_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 1, &unsigned_value);
if (len > 0) {
if (af) {
af->format_class = unsigned_value;
}
apdu_len += len;
} else {
return BACNET_STATUS_ERROR;
}
/* value[2] OctetString */
if (af) {
octet_string_value = &af->value;
} else {
octet_string_value = NULL;
}
len = bacnet_octet_string_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 2, octet_string_value);
if (len > 0) {
apdu_len += len;
} else {
return BACNET_STATUS_ERROR;
}
return apdu_len;
}
/**
* @brief Decode the BACnetAuthenticationFactor complex data
* @param apdu Pointer to the buffer for decoding.
* @param af Pointer to the property decoded data to be stored
* @return Bytes decoded or BACNET_STATUS_REJECT on error.
* @deprecated Use bacnet_authentication_factor_decode() instead
*/
int bacapp_decode_authentication_factor(
const uint8_t *apdu, BACNET_AUTHENTICATION_FACTOR *af)
{
int len;
int apdu_len = 0;
uint32_t format_type = af->format_type;
BACNET_UNSIGNED_INTEGER unsigned_value = 0;
return bacnet_authentication_factor_decode(apdu, MAX_APDU, af);
}
if (decode_is_context_tag(&apdu[apdu_len], 0)) {
len = decode_context_enumerated(&apdu[apdu_len], 0, &format_type);
if (len < 0) {
return -1;
} else if (format_type < AUTHENTICATION_FACTOR_MAX) {
apdu_len += len;
af->format_type = (BACNET_AUTHENTICATION_FACTOR_TYPE)format_type;
} else {
/* FIXME: Maybe this should return BACNET_STATUS_REJECT */
return -1;
}
} else {
return -1;
}
/**
* @brief Decode the context tagged BACnetAuthenticationFactor complex data
* @param apdu Pointer to the buffer for decoding.
* @param apdu_size Number of valid bytes in the buffer.
* @param tag context tag number wrapping the complex data
* @param af Pointer to the property decoded data to be stored, or NULL
* for the length in bytes decoded
* @return Number of bytes decoded,
* 0 if opening tag doesn't match (use to detect OPTIONAL),
* or BACNET_STATUS_ERROR on error.
*/
int bacnet_authentication_factor_context_decode(
const uint8_t *apdu,
unsigned apdu_size,
uint8_t tag,
BACNET_AUTHENTICATION_FACTOR *af)
{
int len = 0, apdu_len = 0;
if (decode_is_context_tag(&apdu[apdu_len], 1)) {
len = decode_context_unsigned(&apdu[apdu_len], 1, &unsigned_value);
if (len < 0) {
return -1;
} else {
af->format_class = unsigned_value;
if (bacnet_is_opening_tag_number(
&apdu[apdu_len], apdu_size - apdu_len, tag, &len)) {
apdu_len += len;
}
} else {
return -1;
}
if (decode_is_context_tag(&apdu[apdu_len], 2)) {
len = decode_context_octet_string(&apdu[apdu_len], 2, &af->value);
if (len < 0) {
return -1;
} else {
len = bacnet_authentication_factor_decode(
&apdu[apdu_len], apdu_size - apdu_len, af);
if (len > 0) {
apdu_len += len;
} else {
return BACNET_STATUS_ERROR;
}
if (bacnet_is_closing_tag_number(
&apdu[apdu_len], apdu_size - apdu_len, tag, &len)) {
apdu_len += len;
} else {
return BACNET_STATUS_ERROR;
}
} else {
return -1;
return 0;
}
return apdu_len;
@@ -137,30 +191,13 @@ int bacapp_decode_authentication_factor(
* @param apdu Pointer to the buffer for decoding.
* @param tag context tag number wrapping the complex data
* @param af Pointer to the property decoded data to be stored
* @return Bytes decoded or BACNET_STATUS_REJECT on error.
* @return Number of bytes decoded,
* 0 if opening tag doesn't match (use to detect OPTIONAL),
* or BACNET_STATUS_ERROR on error.
* @deprecated Use bacnet_authentication_factor_context_decode() instead
*/
int bacapp_decode_context_authentication_factor(
const uint8_t *apdu, uint8_t tag, BACNET_AUTHENTICATION_FACTOR *af)
{
int len = 0;
int section_length;
if (decode_is_opening_tag_number(&apdu[len], tag)) {
len++;
section_length = bacapp_decode_authentication_factor(&apdu[len], af);
if (section_length == -1) {
len = -1;
} else {
len += section_length;
if (decode_is_closing_tag_number(&apdu[len], tag)) {
len++;
} else {
len = -1;
}
}
} else {
len = -1;
}
return len;
return bacnet_authentication_factor_context_decode(apdu, MAX_APDU, tag, af);
}
+14
View File
@@ -31,9 +31,23 @@ int bacapp_encode_authentication_factor(
BACNET_STACK_EXPORT
int bacapp_encode_context_authentication_factor(
uint8_t *apdu, uint8_t tag, const BACNET_AUTHENTICATION_FACTOR *af);
BACNET_STACK_EXPORT
int bacnet_authentication_factor_decode(
const uint8_t *apdu, unsigned apdu_size, BACNET_AUTHENTICATION_FACTOR *af);
BACNET_STACK_DEPRECATED("Use bacnet_authentication_factor_decode() instead")
BACNET_STACK_EXPORT
int bacapp_decode_authentication_factor(
const uint8_t *apdu, BACNET_AUTHENTICATION_FACTOR *af);
BACNET_STACK_EXPORT
int bacnet_authentication_factor_context_decode(
const uint8_t *apdu,
unsigned apdu_size,
uint8_t tag,
BACNET_AUTHENTICATION_FACTOR *af);
BACNET_STACK_DEPRECATED(
"Use bacnet_authentication_factor_context_decode() instead")
BACNET_STACK_EXPORT
int bacapp_decode_context_authentication_factor(
const uint8_t *apdu, uint8_t tag, BACNET_AUTHENTICATION_FACTOR *af);
+255
View File
@@ -5010,6 +5010,35 @@ int bacapp_property_value_encode(
return apdu_len;
}
/**
* @brief Encode one BACnetPropertyValue value within context tags
* @param apdu Pointer to the buffer for encoded values, or NULL for length
* @param tag_number
* @param value Pointer to the service data used for encoding values
* @return Bytes encoded or zero on error.
*/
int bacapp_property_value_context_encode(
uint8_t *apdu, uint8_t tag_number, const BACNET_PROPERTY_VALUE *value)
{
int len = 0; /* length of each encoding */
int apdu_len = 0; /* total length of the apdu, return value */
len = encode_opening_tag(apdu, tag_number);
apdu_len += len;
if (apdu) {
apdu += len;
}
len = bacapp_property_value_encode(apdu, value);
apdu_len += len;
if (apdu) {
apdu += len;
}
len = encode_closing_tag(apdu, tag_number);
apdu_len += len;
return apdu_len;
}
/**
* @brief Decode one BACnetPropertyValue value
*
@@ -5574,3 +5603,229 @@ bool bacapp_same_value(
}
return status;
}
/**
* @brief Encode a BACnetDeviceObjectPropertyValue into a buffer
* BACnetDeviceObjectPropertyValue ::= SEQUENCE {
* device-identifier [0] BACnetObjectIdentifier,
* object-identifier [1] BACnetObjectIdentifier,
* property-identifier [2] BACnetPropertyIdentifier,
* property-array-index [3] Unsigned OPTIONAL,
* -- used only with array datatype
* property-value [4] ABSTRACT-SYNTAX.&Type
* }
* @param apdu - the APDU buffer, or NULL for length
* @param value - BACnetDeviceObjectPropertyValue
* @return length of the APDU buffer
*/
int bacapp_device_object_property_value_encode(
uint8_t *apdu, const BACNET_DEVICE_OBJECT_PROPERTY_VALUE *value)
{
int len = 0;
int apdu_len = 0;
if (!value) {
return 0;
}
len = encode_context_object_id(
apdu, 0, value->device_identifier.type,
value->device_identifier.instance);
apdu_len += len;
if (apdu) {
apdu += len;
}
len = encode_context_object_id(
apdu, 1, value->object_identifier.type,
value->object_identifier.instance);
apdu_len += len;
if (apdu) {
apdu += len;
}
len = encode_context_enumerated(apdu, 2, value->property_identifier);
apdu_len += len;
if (apdu) {
apdu += len;
}
if (value->property_array_index != BACNET_ARRAY_ALL) {
len = encode_context_unsigned(apdu, 3, value->property_array_index);
apdu_len += len;
}
len = encode_opening_tag(apdu, 4);
apdu_len += len;
if (apdu) {
apdu += len;
}
len = bacapp_encode_application_data(apdu, value->value);
apdu_len += len;
if (apdu) {
apdu += len;
}
len = encode_closing_tag(apdu, 4);
apdu_len += len;
return apdu_len;
}
/**
* @brief Decode a BACnetDeviceObjectPropertyValue from a buffer
* BACnetDeviceObjectPropertyValue ::= SEQUENCE {
* device-identifier [0] BACnetObjectIdentifier,
* object-identifier [1] BACnetObjectIdentifier,
* property-identifier [2] BACnetPropertyIdentifier,
* property-array-index [3] Unsigned OPTIONAL,
* -- used only with array datatype
* property-value [4] ABSTRACT-SYNTAX.&Type
* }
* @param apdu - the APDU buffer
* @param apdu_size - the size of the APDU buffer
* @param value - BACnetDeviceObjectPropertyValue to decode into
* @return number of bytes decoded or BACNET_STATUS_ERROR on failure.
*/
int bacapp_device_object_property_value_decode(
uint8_t *apdu,
uint32_t apdu_size,
BACNET_DEVICE_OBJECT_PROPERTY_VALUE *value)
{
int apdu_len = 0;
int len = 0;
BACNET_UNSIGNED_INTEGER array_index = 0;
BACNET_OBJECT_TYPE object_type = 0;
uint32_t object_instance = 0;
uint32_t property_identifier = 0;
BACNET_APPLICATION_DATA_VALUE *property_value = NULL;
if (!apdu) {
return BACNET_STATUS_ERROR;
}
/* device-identifier [0] BACnetObjectIdentifier */
len = bacnet_object_id_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 0, &object_type,
&object_instance);
if (len > 0) {
apdu_len += len;
if (value) {
value->device_identifier.type = object_type;
value->device_identifier.instance = object_instance;
}
} else {
return BACNET_STATUS_ERROR;
}
/* object-identifier [1] BACnetObjectIdentifier */
len = bacnet_object_id_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 1, &object_type,
&object_instance);
if (len > 0) {
apdu_len += len;
if (value) {
value->object_identifier.instance = object_instance;
value->object_identifier.type = object_type;
}
} else {
return len;
}
/* property-identifier [2] BACnetPropertyIdentifier */
len = bacnet_enumerated_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 2, &property_identifier);
if (len > 0) {
apdu_len += len;
if (value) {
value->property_identifier = property_identifier;
}
} else {
return BACNET_STATUS_ERROR;
}
/* property-array-index [3] Unsigned OPTIONAL */
len = bacnet_unsigned_context_decode(
&apdu[apdu_len], apdu_size - apdu_len, 3, &array_index);
if (len > 0) {
apdu_len += len;
if (value) {
value->property_array_index = array_index;
}
} else if (len < 0) {
return BACNET_STATUS_ERROR;
} else {
/* OPTIONAL - skip apdu_len increment */
if (value) {
value->property_array_index = BACNET_ARRAY_ALL;
}
}
if (bacnet_is_opening_tag_number(apdu, apdu_size, 4, &len)) {
/* property-value [4] ABSTRACT-SYNTAX.&Type */
apdu_len += len;
if (value) {
property_value = value->value;
}
len = bacapp_decode_application_data(
&apdu[apdu_len], apdu_size - apdu_len, property_value);
if (len > 0) {
apdu_len += len;
} else {
return BACNET_STATUS_ERROR;
}
if (bacnet_is_closing_tag_number(apdu, apdu_size, 4, &len)) {
apdu_len += len;
} else {
return BACNET_STATUS_ERROR;
}
}
return apdu_len;
}
/**
* @brief Compare the complex data of value1 and value2
* @param value1 - value 1 structure
* @param value2 - value 2 structure
* @return true if the values are the same
*/
bool bacapp_device_object_property_value_same(
const BACNET_DEVICE_OBJECT_PROPERTY_VALUE *value1,
const BACNET_DEVICE_OBJECT_PROPERTY_VALUE *value2)
{
const BACNET_APPLICATION_DATA_VALUE *data_value1, *data_value2;
if (value1 && value2) {
if (!bacnet_object_id_same(
value1->device_identifier.type,
value1->device_identifier.instance,
value2->device_identifier.type,
value2->device_identifier.instance)) {
return false;
}
if (!bacnet_object_id_same(
value1->object_identifier.type,
value1->object_identifier.instance,
value2->object_identifier.type,
value2->object_identifier.instance)) {
return false;
}
if (value1->property_identifier != value2->property_identifier) {
return false;
}
if (value1->property_array_index != value2->property_array_index) {
return false;
}
data_value1 = value1->value;
data_value2 = value2->value;
if (!bacapp_same_value(data_value1, data_value2)) {
return false;
}
return true;
}
return false;
}
/**
* @brief Copy the complex data of src to dest
* @param dest - destination structure
* @param src - source structure
*/
void bacapp_device_object_property_value_copy(
BACNET_DEVICE_OBJECT_PROPERTY_VALUE *dest,
const BACNET_DEVICE_OBJECT_PROPERTY_VALUE *src)
{
if (dest && src) {
memcpy(dest, src, sizeof(BACNET_DEVICE_OBJECT_PROPERTY_VALUE));
}
}
+32
View File
@@ -232,6 +232,18 @@ typedef struct BACnet_Object_Property_Value {
BACNET_APPLICATION_DATA_VALUE *value;
} BACNET_OBJECT_PROPERTY_VALUE;
struct BACnetDeviceObjectPropertyValue;
typedef struct BACnetDeviceObjectPropertyValue {
BACNET_OBJECT_ID device_identifier;
BACNET_OBJECT_ID object_identifier;
BACNET_PROPERTY_ID property_identifier;
/* optional array index */
BACNET_ARRAY_INDEX property_array_index;
BACNET_APPLICATION_DATA_VALUE *value;
/* simple linked list */
struct BACnetDeviceObjectPropertyValue *next;
} BACNET_DEVICE_OBJECT_PROPERTY_VALUE;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
@@ -250,6 +262,9 @@ BACNET_STACK_EXPORT
int bacapp_property_value_encode(
uint8_t *apdu, const BACNET_PROPERTY_VALUE *value);
BACNET_STACK_EXPORT
int bacapp_property_value_context_encode(
uint8_t *apdu, uint8_t tag_number, const BACNET_PROPERTY_VALUE *value);
BACNET_STACK_EXPORT
int bacapp_property_value_decode(
const uint8_t *apdu, uint32_t apdu_size, BACNET_PROPERTY_VALUE *value);
BACNET_STACK_EXPORT
@@ -259,6 +274,23 @@ int bacapp_object_property_value_decode(
BACNET_PROPERTY_VALUE *value,
BACNET_OBJECT_TYPE object_type);
BACNET_STACK_EXPORT
int bacapp_device_object_property_value_encode(
uint8_t *apdu, const BACNET_DEVICE_OBJECT_PROPERTY_VALUE *value);
BACNET_STACK_EXPORT
int bacapp_device_object_property_value_decode(
uint8_t *apdu,
uint32_t apdu_size,
BACNET_DEVICE_OBJECT_PROPERTY_VALUE *value);
BACNET_STACK_EXPORT
bool bacapp_device_object_property_value_same(
const BACNET_DEVICE_OBJECT_PROPERTY_VALUE *value1,
const BACNET_DEVICE_OBJECT_PROPERTY_VALUE *value2);
BACNET_STACK_EXPORT
void bacapp_device_object_property_value_copy(
BACNET_DEVICE_OBJECT_PROPERTY_VALUE *dest,
const BACNET_DEVICE_OBJECT_PROPERTY_VALUE *src);
BACNET_STACK_EXPORT
int bacapp_encode_data(
uint8_t *apdu, const BACNET_APPLICATION_DATA_VALUE *value);
+11 -3
View File
@@ -1309,12 +1309,14 @@ typedef enum BACnetEventType {
EVENT_COMMAND_FAILURE = 3,
EVENT_FLOATING_LIMIT = 4,
EVENT_OUT_OF_RANGE = 5,
/* complex-event-type (6), -- see comment below */
EVENT_COMPLEX_EVENT_TYPE = 6, /* -- see comment below */
/* event-buffer-ready (7), -- context tag 7 is deprecated */
EVENT_CHANGE_OF_LIFE_SAFETY = 8,
EVENT_EXTENDED = 9,
EVENT_BUFFER_READY = 10,
EVENT_UNSIGNED_RANGE = 11,
/* -- context tag 12 is reserved for future addenda
since it conflicts with event-values[12] OPTIONAL */
EVENT_ACCESS_EVENT = 13,
EVENT_DOUBLE_OUT_OF_RANGE = 14,
EVENT_SIGNED_OUT_OF_RANGE = 15,
@@ -1684,6 +1686,8 @@ typedef enum {
BACNET_APPLICATION_TAG_CHANNEL_VALUE,
/* BACnetLogRecord */
BACNET_APPLICATION_TAG_LOG_RECORD,
/* BACnetPropertyValue */
BACNET_APPLICATION_TAG_PROPERTY_VALUE,
/* BACnetTimerStateChangeValue */
BACNET_APPLICATION_TAG_TIMER_VALUE,
/* no-value - context tagged null */
@@ -2625,10 +2629,13 @@ typedef enum BACnetAccessEvent {
ACCESS_EVENT_DENIED_LOCKOUT = 161,
ACCESS_EVENT_DENIED_VERIFICATION_FAILED = 162,
ACCESS_EVENT_DENIED_VERIFICATION_TIMEOUT = 163,
ACCESS_EVENT_DENIED_OTHER = 164
ACCESS_EVENT_DENIED_OTHER = 164,
/* Enumerated values 0-511 are reserved for definition by ASHRAE.
Enumerated values 512-65535 may be used by others subject to
the procedures and constraints described in Clause 23. */
ACCESS_EVENT_PROPRIETARY_MIN = 512,
ACCESS_EVENT_PROPRIETARY_MAX = 65535
} BACNET_ACCESS_EVENT;
/* Authentication Status */
@@ -2961,7 +2968,8 @@ typedef enum BACnetBackupState {
typedef enum BACnetTimerState {
TIMER_STATE_IDLE = 0,
TIMER_STATE_RUNNING = 1,
TIMER_STATE_EXPIRED = 2
TIMER_STATE_EXPIRED = 2,
TIMER_STATE_MAX = 3
} BACNET_TIMER_STATE;
typedef enum BACnetTimerTransition {
+2
View File
@@ -178,6 +178,8 @@ INDTEXT_DATA bacnet_application_tag_names[] = {
{ BACNET_APPLICATION_TAG_ACCESS_RULE, "BACnetAccessRule" },
{ BACNET_APPLICATION_TAG_CHANNEL_VALUE, "BACnetChannelValue" },
{ BACNET_APPLICATION_TAG_LOG_RECORD, "BACnetLogRecord" },
{ BACNET_APPLICATION_TAG_PROPERTY_VALUE, "BACnetPropertyValue" },
{ BACNET_APPLICATION_TAG_LOG_RECORD, "BACnetLogRecord" },
{ BACNET_APPLICATION_TAG_NO_VALUE, "BACnetNoValue" },
{ BACNET_APPLICATION_TAG_ABSTRACT_SYNTAX, "ABSTRACT-SYNTAX" },
{ 0, NULL }
+1 -1
View File
@@ -178,7 +178,7 @@ int dcc_apdu_encode(
}
/**
* @brief Encode the COVNotification service request
* @brief Encode the DeviceCommunicationControl service request
* @param apdu Pointer to the buffer for encoding into
* @param apdu_size number of bytes available in the buffer
* @param timeDuration Optional time duration in minutes.
+2240 -528
View File
File diff suppressed because it is too large Load Diff
+239 -9
View File
@@ -34,10 +34,47 @@ typedef enum {
** Based on UnconfirmedEventNotification-Request
*/
/** Enable decoding of complex-event-type property-values. If set to 0, the
* values are decoded and discarded. */
/** Enable decoding of certain large event parameters.
* If set to 0, the values are decoded and discarded,
* and the encoders are disabled. */
#ifndef BACNET_EVENT_EXTENDED_ENABLED
#define BACNET_EVENT_EXTENDED_ENABLED 0
#endif
#ifndef BACNET_EVENT_DOUBLE_OUT_OF_RANGE_ENABLED
#define BACNET_EVENT_DOUBLE_OUT_OF_RANGE_ENABLED 0
#endif
#ifndef BACNET_EVENT_SIGNED_OUT_OF_RANGE_ENABLED
#define BACNET_EVENT_SIGNED_OUT_OF_RANGE_ENABLED 0
#endif
#ifndef BACNET_EVENT_UNSIGNED_OUT_OF_RANGE_ENABLED
#define BACNET_EVENT_UNSIGNED_OUT_OF_RANGE_ENABLED 0
#endif
#ifndef BACNET_EVENT_CHANGE_OF_CHARACTERSTRING_ENABLED
#define BACNET_EVENT_CHANGE_OF_CHARACTERSTRING_ENABLED 0
#endif
#ifndef BACNET_EVENT_CHANGE_OF_STATUS_FLAGS_ENABLED
#define BACNET_EVENT_CHANGE_OF_STATUS_FLAGS_ENABLED 0
#endif
#ifndef BACNET_EVENT_CHANGE_OF_RELIABILITY_ENABLED
#define BACNET_EVENT_CHANGE_OF_RELIABILITY_ENABLED 0
#endif
#ifndef BACNET_EVENT_CHANGE_OF_DISCRETE_VALUE_ENABLED
#define BACNET_EVENT_CHANGE_OF_DISCRETE_VALUE_ENABLED 0
#endif
#ifndef BACNET_EVENT_CHANGE_OF_TIMER_ENABLED
#define BACNET_EVENT_CHANGE_OF_TIMER_ENABLED 0
#endif
#ifndef BACNET_DECODE_COMPLEX_EVENT_TYPE_PARAMETERS
#define BACNET_DECODE_COMPLEX_EVENT_TYPE_PARAMETERS 1
#define BACNET_DECODE_COMPLEX_EVENT_TYPE_PARAMETERS 0
#endif
/** Max complex-event-type property-values to decode. Events with more values
@@ -46,6 +83,43 @@ typedef enum {
#define BACNET_COMPLEX_EVENT_TYPE_MAX_PARAMETERS 5
#endif
typedef struct BACnetEventExtendedParameter {
uint8_t tag; /* application tag data type */
union {
/* NULL - not needed as it is encoded in the tag alone */
float Real;
bool Boolean;
BACNET_UNSIGNED_INTEGER Unsigned_Int;
int32_t Signed_Int;
double Double;
BACNET_OCTET_STRING *Octet_String;
BACNET_CHARACTER_STRING *Character_String;
BACNET_BIT_STRING *Bit_String;
uint32_t Enumerated;
BACNET_DATE Date;
BACNET_TIME Time;
BACNET_OBJECT_ID Object_Id;
BACNET_DATE_TIME Date_Time;
BACNET_PROPERTY_VALUE *Property_Value;
} type;
} BACNET_EVENT_EXTENDED_PARAMETER;
typedef struct BACnetEventDiscreteValue {
uint8_t tag; /* application tag data type */
union {
bool Boolean;
BACNET_UNSIGNED_INTEGER Unsigned_Int;
int32_t Signed_Int;
uint32_t Enumerated;
BACNET_CHARACTER_STRING *Character_String;
BACNET_OCTET_STRING *Octet_String;
BACNET_DATE Date;
BACNET_TIME Time;
BACNET_OBJECT_ID Object_Id;
BACNET_DATE_TIME Date_Time;
} type;
} BACNET_EVENT_DISCRETE_VALUE;
typedef struct BACnet_Event_Notification_Data {
uint32_t processIdentifier;
BACNET_OBJECT_ID initiatingObjectIdentifier;
@@ -133,11 +207,34 @@ typedef struct BACnet_Event_Notification_Data {
BACNET_BIT_STRING statusFlags;
BACNET_LIFE_SAFETY_OPERATION operationExpected;
} changeOfLifeSafety;
/*
** EVENT_EXTENDED
**
** Not Supported!
*/
#if BACNET_EVENT_EXTENDED_ENABLED
/* EVENT_EXTENDED
extended [9] SEQUENCE {
vendor-id [0] Unsigned16,
extended-event-type [1] Unsigned,
parameters [2] SEQUENCE OF CHOICE {
null NULL,
real REAL,
unsigned Unsigned,
boolean BOOLEAN,
integer INTEGER,
double Double,
octetstring OCTET STRING,
characterstring CharacterString,
bitstring BIT STRING,
enumerated ENUMERATED,
date Date,
time Time,
objectidentifier BACnetObjectIdentifier,
property-value [0] BACnetDeviceObjectPropertyValue
}
} */
struct {
uint16_t vendorID;
BACNET_UNSIGNED_INTEGER extendedEventType;
BACNET_EVENT_EXTENDED_PARAMETER parameters;
} extended;
#endif
/*
** EVENT_BUFFER_READY
*/
@@ -167,7 +264,140 @@ typedef struct BACnet_Event_Notification_Data {
/* OPTIONAL - Set authenticationFactor.format_type to
AUTHENTICATION_FACTOR_MAX if not being used */
} accessEvent;
#if (BACNET_DECODE_COMPLEX_EVENT_TYPE_PARAMETERS == 1)
#if BACNET_EVENT_DOUBLE_OUT_OF_RANGE_ENABLED
/* EVENT_DOUBLE_OUT_OF_RANGE
double-out-of-range[14] SEQUENCE {
exceeding-value[0] Double,
status-flags[1] BACnetStatusFlags,
deadband[2] Double,
exceeded-limit[3] Double
} */
struct {
double exceedingValue;
BACNET_BIT_STRING statusFlags;
double deadband;
double exceededLimit;
} doubleOutOfRange;
#endif
#if BACNET_EVENT_SIGNED_OUT_OF_RANGE_ENABLED
/* EVENT_SIGNED_OUT_OF_RANGE
signed-out-of-range[14] SEQUENCE {
exceeding-value[0] Integer,
status-flags[1] BACnetStatusFlags,
deadband[2] Unsigned,
exceeded-limit[3] Integer
} */
struct {
int32_t exceedingValue;
BACNET_BIT_STRING statusFlags;
uint32_t deadband;
int32_t exceededLimit;
} signedOutOfRange;
#endif
#if BACNET_EVENT_UNSIGNED_OUT_OF_RANGE_ENABLED
/* EVENT_UNSIGNED_OUT_OF_RANGE
unsigned-out-of-range[14] SEQUENCE {
exceeding-value[0] Unsigned,
status-flags[1] BACnetStatusFlags,
deadband[2] Unsigned,
exceeded-limit[3] Unsigned
} */
struct {
BACNET_UNSIGNED_INTEGER exceedingValue;
BACNET_BIT_STRING statusFlags;
BACNET_UNSIGNED_INTEGER deadband;
BACNET_UNSIGNED_INTEGER exceededLimit;
} unsignedOutOfRange;
#endif
#if BACNET_EVENT_CHANGE_OF_CHARACTERSTRING_ENABLED
/* EVENT_CHANGE_OF_CHARACTERSTRING
change-of-characterstring [17] SEQUENCE {
changed-value [0] CharacterString,
status-flags [1] BACnetStatusFlags,
alarm-value [2] CharacterString
} */
struct {
BACNET_CHARACTER_STRING *changedValue;
BACNET_BIT_STRING statusFlags;
BACNET_CHARACTER_STRING *alarmValue;
} changeOfCharacterstring;
#endif
#if BACNET_EVENT_CHANGE_OF_STATUS_FLAGS_ENABLED
/* EVENT_CHANGE_OF_STATUS_FLAGS
change-of-status-flags [18] SEQUENCE {
present-value [0] ABSTRACT-SYNTAX.&Type OPTIONAL,
-- depends on referenced property
referenced-flags [1] BACnetStatusFlags
} */
/* OPTIONAL - Set present-value.tag to
BACNET_APPLICATION_TAG_EMPTYLIST if not used */
struct {
BACNET_EVENT_EXTENDED_PARAMETER presentValue;
BACNET_BIT_STRING referencedFlags;
} changeOfStatusFlags;
#endif
#if BACNET_EVENT_CHANGE_OF_RELIABILITY_ENABLED
/* EVENT_CHANGE_OF_RELIABILITY
change-of-reliability [19] SEQUENCE {
reliability [0] BACnetReliability,
status-flags [1] BACnetStatusFlags,
property-values [2] SEQUENCE OF BACnetPropertyValue
} */
struct {
BACNET_RELIABILITY reliability;
BACNET_BIT_STRING statusFlags;
BACNET_PROPERTY_VALUE *propertyValues;
} changeOfReliability;
#endif
#if BACNET_EVENT_CHANGE_OF_DISCRETE_VALUE_ENABLED
/* EVENT_CHANGE_OF_DISCRETE_VALUE
change-of-discrete-value [21] SEQUENCE {
new-value [0] CHOICE {
boolean BOOLEAN,
unsigned Unsigned,
integer INTEGER,
enumerated ENUMERATED,
characterstring CharacterString,
octetstring OCTET STRING,
date Date,
time Time,
objectidentifier BACnetObjectIdentifier,
datetime [0] BACnetDateTime
},
status-flags [1] BACnetStatusFlags
}*/
struct {
BACNET_EVENT_DISCRETE_VALUE newValue;
BACNET_BIT_STRING statusFlags;
} changeOfDiscreteValue;
#endif
#if BACNET_EVENT_CHANGE_OF_TIMER_ENABLED
/* EVENT_CHANGE_OF_TIMER
change-of-timer [22] SEQUENCE {
new-state [0] BACnetTimerState,
status-flags [1] BACnetStatusFlags,
update-time [2] BACnetDateTime,
last-state-change [3] BACnetTimerTransition OPTIONAL,
initial-timeout [4] Unsigned OPTIONAL,
expiration-time [5] BACnetDateTime OPTIONAL
} */
/* OPTIONAL - Set last-state-change to TIMER_TRANSITION_MAX
if not used. */
/* OPTIONAL - Set expiration-time to wildcards if not used. */
/* OPTIONAL - Set initial-timeout to 0 if not used. */
struct {
BACNET_TIMER_STATE newState;
BACNET_BIT_STRING statusFlags;
BACNET_DATE_TIME updateTime;
BACNET_TIMER_TRANSITION lastStateChange;
BACNET_UNSIGNED_INTEGER initialTimeout;
BACNET_DATE_TIME expirationTime;
} changeOfTimer;
#endif
/*
** EVENT_NONE - tag only
*/
#if BACNET_DECODE_COMPLEX_EVENT_TYPE_PARAMETERS
/*
* complex-event-type - a sequence of values, used for proprietary event
* types
+1 -1
View File
@@ -68,7 +68,7 @@ int reinitialize_device_encode(
}
/**
* @brief Encode the COVNotification service request
* @brief Encode the ReinitializeDevice-Request service
* @param apdu Pointer to the buffer for encoding into
* @param apdu_size number of bytes available in the buffer
* @param state Reinitialization state
+1 -1
View File
@@ -270,7 +270,7 @@ int read_property_ack_encode(
}
/**
* @brief Encode the COVNotification service request
* @brief Encode the ReadProperty-ACK service
* @param apdu Pointer to the buffer for encoding into
* @param apdu_size number of bytes available in the buffer
* @param data Pointer to the service data used for encoding values
+10
View File
@@ -23,6 +23,16 @@ set(ZTST_DIR "${TST_DIR}/ztest/src")
add_compile_definitions(
BIG_ENDIAN=0
CONFIG_ZTEST=1
BACNET_EVENT_EXTENDED_ENABLED=1
BACNET_EVENT_DOUBLE_OUT_OF_RANGE_ENABLED=1
BACNET_EVENT_SIGNED_OUT_OF_RANGE_ENABLED=1
BACNET_EVENT_UNSIGNED_OUT_OF_RANGE_ENABLED=1
BACNET_EVENT_CHANGE_OF_CHARACTERSTRING_ENABLED=1
BACNET_EVENT_CHANGE_OF_STATUS_FLAGS_ENABLED=1
BACNET_EVENT_CHANGE_OF_RELIABILITY_ENABLED=1
BACNET_EVENT_CHANGE_OF_DISCRETE_VALUE_ENABLED=1
BACNET_EVENT_CHANGE_OF_TIMER_ENABLED=1
BACNET_DECODE_COMPLEX_EVENT_TYPE_PARAMETERS=1
)
include_directories(
+1407 -611
View File
File diff suppressed because it is too large Load Diff