Refactor/write property object name (#504)

* refactor WriteProperty of object-name property rules into device object.

* remove dependence on device object inside some dynamic objects

* improve device object unit test coverage

---------

Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
Steve Karg
2023-09-28 15:30:28 -05:00
committed by GitHub
parent 95c2a86041
commit c9a85a1282
16 changed files with 304 additions and 200 deletions
+74 -6
View File
@@ -55,9 +55,6 @@
/* local forward (semi-private) and external prototypes */
int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata);
bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data);
extern int Routed_Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata);
extern bool Routed_Device_Write_Property_Local(
BACNET_WRITE_PROPERTY_DATA *wp_data);
/* may be overridden by outside table */
static object_functions_t *Object_Table;
@@ -1508,6 +1505,73 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
return status;
}
/**
* @brief Handles the writing of the object name property
* @param wp_data [in,out] WriteProperty data structure
* @param Object_Write_Property object specific function to write the property
* @return True on success, else False if there is an error.
*/
static bool Device_Write_Property_Object_Name(
BACNET_WRITE_PROPERTY_DATA *wp_data,
write_property_function Object_Write_Property)
{
bool status = false; /* return value */
int len = 0;
BACNET_CHARACTER_STRING value;
BACNET_OBJECT_TYPE object_type = OBJECT_NONE;
uint32_t object_instance = 0;
int apdu_size = 0;
uint8_t *apdu = NULL;
if (!wp_data) {
return false;
}
if (wp_data->array_index != BACNET_ARRAY_ALL) {
/* only array properties can have array options */
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
return false;
}
apdu = wp_data->application_data;
apdu_size = wp_data->application_data_len;
len = bacnet_character_string_application_decode(apdu, apdu_size, &value);
if (len > 0) {
if ((characterstring_encoding(&value) != CHARACTER_ANSI_X34) ||
(characterstring_length(&value) == 0) ||
(!characterstring_printable(&value))) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} else {
status = true;
}
} else if (len == 0) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
} else {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
if (status) {
/* All the object names in a device must be unique */
if (Device_Valid_Object_Name(&value, &object_type, &object_instance)) {
if ((object_type == wp_data->object_type) &&
(object_instance == wp_data->object_instance)) {
/* writing same name to same object */
status = true;
} else {
/* name already exists in some object */
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_DUPLICATE_NAME;
status = false;
}
} else {
status = Object_Write_Property(wp_data);
}
}
return status;
}
/** Looks up the requested Object and Property, and set the new Value in it,
* if allowed.
* If the Object or Property can't be found, sets the error class and code.
@@ -1534,10 +1598,14 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
if (wp_data->object_property == PROP_PROPERTY_LIST) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else
return false;
}
#endif
{
status = pObject->Object_Write_Property(wp_data);
if (wp_data->object_property == PROP_OBJECT_NAME) {
status = Device_Write_Property_Object_Name(wp_data,
pObject->Object_Write_Property);
} else {
status = pObject->Object_Write_Property(wp_data);
}
} else {
wp_data->error_class = ERROR_CLASS_PROPERTY;