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:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
/**
|
||||
* @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 (bacnet_is_opening_tag_number(
|
||||
&apdu[apdu_len], apdu_size - apdu_len, tag, &len)) {
|
||||
apdu_len += len;
|
||||
len = bacnet_authentication_factor_decode(
|
||||
&apdu[apdu_len], apdu_size - apdu_len, af);
|
||||
if (len > 0) {
|
||||
apdu_len += len;
|
||||
af->format_type = (BACNET_AUTHENTICATION_FACTOR_TYPE)format_type;
|
||||
} else {
|
||||
/* FIXME: Maybe this should return BACNET_STATUS_REJECT */
|
||||
return -1;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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 {
|
||||
apdu_len += len;
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
+2351
-639
File diff suppressed because it is too large
Load Diff
+239
-9
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user