Secure ReadProperty decoding and BACnetActionCommand (#702)

* Refactored and secured BACnetActionCommand codec into bacaction.c module for command object and added to bacapp module encode/decode with define for enabling and pseudo application tag for internal use.

* Simplified bacapp_data_len() and moved into bacdcode module as bacnet_enclosed_data_len() function.

* Secured ReadProperty-REQUEST and -ACK decoding.

* Removed deprecated Keylist_Key() functions from usage.

* Removed pseudo application datatypes from bacapp_data_decode() which only uses primitive application tag encoded values.

* Defined INT_MAX when it is not already defined by compiler or libc.

* Deprecated bacapp_decode_application_data_len() and bacapp_decode_context_data_len() as they are no longer used in any code in the library.

* Added BACnetScale to bacapp module. Improved complex property value decoding. Refactored bacapp_decode_known_property() function.

* Refactored and improved the bacapp_snprintf() function for printing EPICS.

* Fixed Lighting Output WriteProperty to handle known property decoding.
This commit is contained in:
Steve Karg
2024-07-25 17:12:08 -05:00
committed by GitHub
parent 923eaf2313
commit 4326128e72
191 changed files with 3856 additions and 2099 deletions
+81 -61
View File
@@ -2,7 +2,7 @@
* @file
* @author Steve Karg <skarg@users.sourceforge.net>
* @date 2016
* @brief A basic BACnet Network Port object provides access to the
* @brief A basic BACnet Network Port object provides access to the
* configuration and properties of any network ports of a device.
* @copyright SPDX-License-Identifier: MIT
*/
@@ -2898,7 +2898,75 @@ static bool Network_Port_FD_BBMD_Address_Write(
#endif
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
}
return status;
}
/**
* @brief Write the FD Subscription Lifetime
* @param object_instance [in] BACnet network port object instance number
* @param value [in] BACnet IP address and port
* @param error_class [out] BACnet error class
* @param error_code [out] BACnet error code
* @return true if the value was written
*/
static bool Network_Port_FD_Subscription_Lifetime_Write(
uint32_t object_instance,
BACNET_UNSIGNED_INTEGER value,
BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code)
{
bool status = false;
uint16_t lifetime = 0;
if (!error_class || !error_code) {
return status;
}
if (value > UINT16_MAX) {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
return status;
}
lifetime = (uint16_t)value;
switch (Network_Port_Type(object_instance)) {
#if (defined(BACDL_ALL) || defined(BACDL_BIP))
case PORT_TYPE_BIP:
if (Network_Port_BIP_Mode(object_instance) ==
BACNET_IP_MODE_FOREIGN) {
status = Network_Port_Remote_BBMD_BIP_Lifetime_Set(
object_instance, lifetime);
if (!status) {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
}
break;
#endif
#if (defined(BACDL_ALL) || defined(BACDL_BIP6))
case PORT_TYPE_BIP6:
if (Network_Port_BIP6_Mode(object_instance) ==
BACNET_IP_MODE_FOREIGN) {
status = Network_Port_Remote_BBMD_BIP6_Lifetime_Set(
object_instance, lifetime);
if (!status) {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
}
break;
#endif
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
}
@@ -3379,13 +3447,13 @@ bool Network_Port_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
return false;
}
/* decode the some of the request */
#if !defined(BACAPP_COMPLEX_TYPES)
#if defined(BACAPP_COMPLEX_TYPES)
len = bacapp_decode_known_property(
wp_data->application_data, wp_data->application_data_len, &value,
wp_data->object_type, wp_data->object_property);
#else
len = bacapp_decode_application_data(
wp_data->application_data, wp_data->application_data_len, &value);
#else
len = bacapp_decode_generic_property(
wp_data->application_data, wp_data->application_data_len, &value,
wp_data->object_property);
#endif
if (len < 0) {
/* error while decoding - a value larger than we can handle */
@@ -3462,60 +3530,12 @@ bool Network_Port_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
case PROP_FD_SUBSCRIPTION_LIFETIME:
if (write_property_type_valid(
wp_data, &value, BACNET_APPLICATION_TAG_UNSIGNED_INT)) {
if (value.type.Unsigned_Int <= 65535) {
switch (Network_Port_Type(wp_data->object_instance)) {
#if (defined(BACDL_ALL) || defined(BACDL_BIP))
case PORT_TYPE_BIP:
if (Network_Port_BIP_Mode(
wp_data->object_instance) ==
BACNET_IP_MODE_FOREIGN) {
status =
Network_Port_Remote_BBMD_BIP_Lifetime_Set(
wp_data->object_instance,
value.type.Unsigned_Int);
if (!status) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code =
ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code =
ERROR_CODE_WRITE_ACCESS_DENIED;
}
break;
#endif
#if (defined(BACDL_ALL) || defined(BACDL_BIP6))
case PORT_TYPE_BIP6:
if (Network_Port_BIP6_Mode(
wp_data->object_instance) ==
BACNET_IP_MODE_FOREIGN) {
status =
Network_Port_Remote_BBMD_BIP6_Lifetime_Set(
wp_data->object_instance,
value.type.Unsigned_Int);
if (!status) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code =
ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code =
ERROR_CODE_WRITE_ACCESS_DENIED;
}
break;
#endif
default:
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code =
ERROR_CODE_INVALID_ARRAY_INDEX;
break;
}
} else {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
status = Network_Port_FD_Subscription_Lifetime_Write(
wp_data->object_instance, value.type.Unsigned_Int,
&wp_data->error_class, &wp_data->error_code);
} else {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
break;
#endif