Fixed WriteProperty bypass which is only for present-value property of commandable objects. (#984)
This commit is contained in:
@@ -40,6 +40,12 @@
|
||||
* the property shall not be changed, and the write shall
|
||||
* be considered successful.
|
||||
*
|
||||
* @note There was an interpretation request in April 2025 that clarifies
|
||||
* that the NULL bypass is only for present-value property of objects that
|
||||
* optionally support a priority array but don't implement it.
|
||||
* See 135-2024-19.2.1.1 Commandable Properties for the list of commandable
|
||||
* properties of specific objects.
|
||||
*
|
||||
* @param wp_data [in] The WriteProperty data structure
|
||||
* @return true if the write shall be considered successful
|
||||
*/
|
||||
|
||||
@@ -534,3 +534,53 @@ bool property_list_bacnet_list_member(
|
||||
|
||||
return property_list_member(Properties_BACnetLIST, object_property);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine if the object property is a commandable member
|
||||
*
|
||||
* 19.2.1.1 Commandable Properties
|
||||
* The prioritization scheme is applied to certain properties of objects.
|
||||
* The standard commandable properties and objects are as follows.
|
||||
*
|
||||
* @param object_type - object-type to be checked
|
||||
* @param object_property - object-property to be checked
|
||||
* @return true if the property is a commandable member
|
||||
*/
|
||||
bool property_list_commandable_member(
|
||||
BACNET_OBJECT_TYPE object_type, BACNET_PROPERTY_ID object_property)
|
||||
{
|
||||
bool status = false;
|
||||
|
||||
switch (object_type) {
|
||||
case OBJECT_ACCESS_DOOR:
|
||||
case OBJECT_ANALOG_OUTPUT:
|
||||
case OBJECT_ANALOG_VALUE:
|
||||
case OBJECT_BINARY_LIGHTING_OUTPUT:
|
||||
case OBJECT_BINARY_OUTPUT:
|
||||
case OBJECT_BINARY_VALUE:
|
||||
case OBJECT_BITSTRING_VALUE:
|
||||
case OBJECT_CHANNEL:
|
||||
case OBJECT_CHARACTERSTRING_VALUE:
|
||||
case OBJECT_DATE_VALUE:
|
||||
case OBJECT_DATE_PATTERN_VALUE:
|
||||
case OBJECT_DATETIME_VALUE:
|
||||
case OBJECT_DATETIME_PATTERN_VALUE:
|
||||
case OBJECT_INTEGER_VALUE:
|
||||
case OBJECT_LARGE_ANALOG_VALUE:
|
||||
case OBJECT_LIGHTING_OUTPUT:
|
||||
case OBJECT_MULTI_STATE_OUTPUT:
|
||||
case OBJECT_MULTI_STATE_VALUE:
|
||||
case OBJECT_OCTETSTRING_VALUE:
|
||||
case OBJECT_POSITIVE_INTEGER_VALUE:
|
||||
case OBJECT_TIME_VALUE:
|
||||
case OBJECT_TIME_PATTERN_VALUE:
|
||||
if (object_property == PROP_PRESENT_VALUE) {
|
||||
status = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,9 @@ const int *property_list_bacnet_list(void);
|
||||
BACNET_STACK_EXPORT
|
||||
bool property_list_bacnet_list_member(
|
||||
BACNET_OBJECT_TYPE object_type, BACNET_PROPERTY_ID object_property);
|
||||
BACNET_STACK_EXPORT
|
||||
bool property_list_commandable_member(
|
||||
BACNET_OBJECT_TYPE object_type, BACNET_PROPERTY_ID object_property);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+21
-15
@@ -500,6 +500,12 @@ bool write_property_unsigned_decode(
|
||||
* the property shall not be changed, and the write shall
|
||||
* be considered successful.
|
||||
*
|
||||
* @note There was an interpretation request in April 2025 that clarifies
|
||||
* that the NULL bypass is only for present-value property of objects that
|
||||
* optionally support a priority array but don't implement it.
|
||||
* See 135-2024-19.2.1.1 Commandable Properties for the list of commandable
|
||||
* properties of specific objects.
|
||||
*
|
||||
* @param wp_data [in] The WriteProperty data structure
|
||||
* @param member_of_object [in] Function to check if a property is a member
|
||||
of an object instance
|
||||
@@ -520,25 +526,25 @@ bool write_property_relinquish_bypass(
|
||||
wp_data->application_data, wp_data->application_data_len);
|
||||
if ((len > 0) && (len == wp_data->application_data_len)) {
|
||||
/* single NULL */
|
||||
/* check to see if this object property is commandable.
|
||||
Does the property list contain a priority-array? */
|
||||
if (member_of_object) {
|
||||
has_priority_array = member_of_object(
|
||||
wp_data->object_type, wp_data->object_instance,
|
||||
PROP_PRIORITY_ARRAY);
|
||||
}
|
||||
if (has_priority_array || (wp_data->object_type == OBJECT_CHANNEL)) {
|
||||
if (wp_data->object_property != PROP_PRESENT_VALUE) {
|
||||
/* this property is not commandable,
|
||||
if (property_list_commandable_member(
|
||||
wp_data->object_type, wp_data->object_property)) {
|
||||
if (member_of_object) {
|
||||
/* check to see if this object property is commandable.
|
||||
Does the property list contain a priority-array? */
|
||||
has_priority_array = member_of_object(
|
||||
wp_data->object_type, wp_data->object_instance,
|
||||
PROP_PRIORITY_ARRAY);
|
||||
}
|
||||
if (has_priority_array ||
|
||||
(wp_data->object_type == OBJECT_CHANNEL)) {
|
||||
/* this property is commandable and shall not be bypassed */
|
||||
} else {
|
||||
/* this property that is optionally commandable
|
||||
is not commandable for this object instance,
|
||||
so it "shall not be changed, and
|
||||
the write shall be considered successful." */
|
||||
bypass = true;
|
||||
}
|
||||
} else {
|
||||
/* this object is not commandable, so any property
|
||||
written with a NULL "shall not be changed, and
|
||||
the write shall be considered successful." */
|
||||
bypass = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user