feat: add Last_Restart_Reason property support to Device object (#1323)
This commit is contained in:
@@ -1184,7 +1184,8 @@ typedef enum BACnetRestartReason {
|
||||
compilers will allocate adequate sized datatype for enum
|
||||
which is used to store decoding */
|
||||
RESTART_REASON_PROPRIETARY_MIN = 64,
|
||||
RESTART_REASON_PROPRIETARY_MAX = 255
|
||||
RESTART_REASON_PROPRIETARY_MAX = 255,
|
||||
BACNET_RESTART_REASON_MAX = 256
|
||||
} BACNET_RESTART_REASON;
|
||||
|
||||
typedef enum BACnetPropertyStates {
|
||||
|
||||
@@ -1279,6 +1279,7 @@ static const int32_t Device_Properties_Optional[] = {
|
||||
PROP_ACTIVE_COV_SUBSCRIPTIONS,
|
||||
PROP_SERIAL_NUMBER,
|
||||
PROP_TIME_OF_DEVICE_RESTART,
|
||||
PROP_LAST_RESTART_REASON,
|
||||
#if defined(BACNET_TIME_MASTER)
|
||||
PROP_TIME_SYNCHRONIZATION_RECIPIENTS,
|
||||
PROP_TIME_SYNCHRONIZATION_INTERVAL,
|
||||
@@ -1331,7 +1332,10 @@ static const int32_t Writable_Properties[] = {
|
||||
PROP_BACKUP_PREPARATION_TIME,
|
||||
PROP_RESTORE_PREPARATION_TIME,
|
||||
#endif
|
||||
#if defined(BACAPP_TIMESTAMP)
|
||||
PROP_TIME_OF_DEVICE_RESTART,
|
||||
#endif
|
||||
PROP_LAST_RESTART_REASON,
|
||||
-1
|
||||
};
|
||||
|
||||
@@ -1434,6 +1438,7 @@ static uint8_t Device_UUID[16];
|
||||
/* static uint8_t Max_Segments_Accepted = 0; */
|
||||
/* VT_Classes_Supported */
|
||||
/* Active_VT_Sessions */
|
||||
static BACNET_RESTART_REASON Last_Restart_Reason = RESTART_REASON_UNKNOWN;
|
||||
static BACNET_TIMESTAMP Time_Of_Device_Restart;
|
||||
static BACNET_TIME Local_Time; /* rely on OS, if there is one */
|
||||
static BACNET_DATE Local_Date; /* rely on OS, if there is one */
|
||||
@@ -2058,6 +2063,33 @@ bool Device_Serial_Number_Set(const char *str, size_t length)
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the device last-restart-reason property value.
|
||||
* @param restart_reason [in] The new device last-restart-reason, as a
|
||||
* BACNET_RESTART_REASON.
|
||||
* @return true if the device last-restart-reason was set
|
||||
*/
|
||||
bool Device_Last_Restart_Reason_Set(const BACNET_RESTART_REASON restart_reason)
|
||||
{
|
||||
bool status = false; /*return value */
|
||||
|
||||
if (restart_reason < BACNET_RESTART_REASON_MAX) {
|
||||
Last_Restart_Reason = restart_reason;
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the device last-restart-reason property value.
|
||||
* @return The device last-restart-reason, as a BACNET_RESTART_REASON.
|
||||
*/
|
||||
BACNET_RESTART_REASON Device_Last_Restart_Reason(void)
|
||||
{
|
||||
return Last_Restart_Reason;
|
||||
}
|
||||
|
||||
void Device_Time_Of_Restart(BACNET_TIMESTAMP *time_of_restart)
|
||||
{
|
||||
bacapp_timestamp_copy(time_of_restart, &Time_Of_Device_Restart);
|
||||
@@ -2559,10 +2591,10 @@ static BACNET_ERROR_CODE Device_Configuration_File_Write(
|
||||
(void)object_instance;
|
||||
if (array_index == 0) {
|
||||
/* This array is not required to be resizable
|
||||
through BACnet write services */
|
||||
through BACnet write services */
|
||||
(void)array_size;
|
||||
error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
} else {
|
||||
} else if (array_index <= BACNET_BACKUP_FILE_COUNT) {
|
||||
len = bacnet_object_id_application_decode(
|
||||
application_data, application_data_len, &object_type, &instance);
|
||||
if (len > 0) {
|
||||
@@ -2579,6 +2611,8 @@ static BACNET_ERROR_CODE Device_Configuration_File_Write(
|
||||
} else {
|
||||
error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
}
|
||||
} else {
|
||||
error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||
}
|
||||
|
||||
return error_code;
|
||||
@@ -2979,6 +3013,10 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
apdu_len =
|
||||
bacapp_encode_timestamp(&apdu[0], &Time_Of_Device_Restart);
|
||||
break;
|
||||
case PROP_LAST_RESTART_REASON:
|
||||
apdu_len =
|
||||
encode_application_enumerated(&apdu[0], Last_Restart_Reason);
|
||||
break;
|
||||
default:
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
@@ -3351,14 +3389,26 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined(BACAPP_TIMESTAMP)
|
||||
case PROP_TIME_OF_DEVICE_RESTART:
|
||||
status = write_property_type_valid(
|
||||
wp_data, &value, BACNET_APPLICATION_TAG_TIMESTAMP);
|
||||
if (status) {
|
||||
#if defined(BACAPP_TIMESTAMP)
|
||||
bacapp_timestamp_copy(
|
||||
&Time_Of_Device_Restart, &value.type.Time_Stamp);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case PROP_LAST_RESTART_REASON:
|
||||
status = write_property_type_valid(
|
||||
wp_data, &value, BACNET_APPLICATION_TAG_ENUMERATED);
|
||||
if (status) {
|
||||
status = Device_Last_Restart_Reason_Set(
|
||||
(BACNET_RESTART_REASON)value.type.Unsigned_Int);
|
||||
if (!status) {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -417,6 +417,11 @@ const char *Device_Serial_Number(void);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Device_Serial_Number_Set(const char *name, size_t length);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Device_Last_Restart_Reason_Set(const BACNET_RESTART_REASON restart_reason);
|
||||
BACNET_STACK_EXPORT
|
||||
BACNET_RESTART_REASON Device_Last_Restart_Reason(void);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void Device_Time_Of_Restart(BACNET_TIMESTAMP *time_of_restart);
|
||||
BACNET_STACK_EXPORT
|
||||
|
||||
@@ -1215,6 +1215,7 @@ static const int32_t Device_Properties_Optional[] = {
|
||||
#endif
|
||||
PROP_SERIAL_NUMBER,
|
||||
PROP_TIME_OF_DEVICE_RESTART,
|
||||
PROP_LAST_RESTART_REASON,
|
||||
#if defined(BACNET_TIME_MASTER)
|
||||
PROP_TIME_SYNCHRONIZATION_RECIPIENTS,
|
||||
PROP_TIME_SYNCHRONIZATION_INTERVAL,
|
||||
@@ -1268,6 +1269,7 @@ static const int32_t Writable_Properties[] = {
|
||||
PROP_RESTORE_PREPARATION_TIME,
|
||||
#endif
|
||||
PROP_TIME_OF_DEVICE_RESTART,
|
||||
PROP_LAST_RESTART_REASON,
|
||||
-1
|
||||
};
|
||||
|
||||
@@ -1368,6 +1370,7 @@ static list_element_function Device_Add_List_Element_Callback;
|
||||
static list_element_function Device_Remove_List_Element_Callback;
|
||||
static uint8_t Device_UUID[16];
|
||||
static const char *Serial_Number = BACNET_DEVICE_SERIAL_NUMBER;
|
||||
static BACNET_RESTART_REASON Last_Restart_Reason = RESTART_REASON_UNKNOWN;
|
||||
static BACNET_TIMESTAMP Time_Of_Device_Restart;
|
||||
static BACNET_TIME Local_Time; /* rely on OS, if there is one */
|
||||
static BACNET_DATE Local_Date; /* rely on OS, if there is one */
|
||||
@@ -1933,6 +1936,33 @@ bool Device_Serial_Number_Set(const char *str, size_t length)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the device last-restart-reason property value.
|
||||
* @param restart_reason [in] The new device last-restart-reason, as a
|
||||
* BACNET_RESTART_REASON.
|
||||
* @return true if the device last-restart-reason was set
|
||||
*/
|
||||
bool Device_Last_Restart_Reason_Set(const BACNET_RESTART_REASON restart_reason)
|
||||
{
|
||||
bool status = false; /*return value */
|
||||
|
||||
if (restart_reason < BACNET_RESTART_REASON_MAX) {
|
||||
Last_Restart_Reason = restart_reason;
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the device last-restart-reason property value.
|
||||
* @return The device last-restart-reason, as a BACNET_RESTART_REASON.
|
||||
*/
|
||||
BACNET_RESTART_REASON Device_Last_Restart_Reason(void)
|
||||
{
|
||||
return Last_Restart_Reason;
|
||||
}
|
||||
|
||||
void Device_Time_Of_Restart(BACNET_TIMESTAMP *time_of_restart)
|
||||
{
|
||||
bacapp_timestamp_copy(time_of_restart, &Time_Of_Device_Restart);
|
||||
@@ -2843,6 +2873,10 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
apdu_len =
|
||||
bacapp_encode_timestamp(&apdu[0], &Time_Of_Device_Restart);
|
||||
break;
|
||||
case PROP_LAST_RESTART_REASON:
|
||||
apdu_len =
|
||||
encode_application_enumerated(&apdu[0], Last_Restart_Reason);
|
||||
break;
|
||||
default:
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
@@ -3225,6 +3259,18 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case PROP_LAST_RESTART_REASON:
|
||||
status = write_property_type_valid(
|
||||
wp_data, &value, BACNET_APPLICATION_TAG_ENUMERATED);
|
||||
if (status) {
|
||||
status = Device_Last_Restart_Reason_Set(
|
||||
(BACNET_RESTART_REASON)value.type.Unsigned_Int);
|
||||
if (!status) {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (property_lists_member(
|
||||
Device_Properties_Required, Device_Properties_Optional,
|
||||
|
||||
@@ -464,6 +464,38 @@ static void testDevice(void)
|
||||
zassert_true(property_list.Required.count > 0, NULL);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Test Device_Last_Restart_Reason_Set() and Device_Last_Restart_Reason()
|
||||
*/
|
||||
static void test_Device_Last_Restart_Reason(void)
|
||||
{
|
||||
BACNET_RESTART_REASON reason;
|
||||
bool status;
|
||||
unsigned i;
|
||||
|
||||
Device_Init(NULL);
|
||||
/* default value after init shall be RESTART_REASON_UNKNOWN */
|
||||
reason = Device_Last_Restart_Reason();
|
||||
zassert_equal(reason, RESTART_REASON_UNKNOWN, NULL);
|
||||
|
||||
/* loop over every valid value (0..BACNET_RESTART_REASON_MAX-1) */
|
||||
for (i = 0; i < BACNET_RESTART_REASON_MAX; i++) {
|
||||
reason = (BACNET_RESTART_REASON)i;
|
||||
status = Device_Last_Restart_Reason_Set(reason);
|
||||
zassert_true(status, "reason=%u rejected", i);
|
||||
zassert_equal(
|
||||
Device_Last_Restart_Reason(), reason, "reason=%u mismatch", i);
|
||||
}
|
||||
|
||||
/* BACNET_RESTART_REASON_MAX (256) is out-of-range and must be rejected;
|
||||
* the previously stored value shall be unchanged */
|
||||
status = Device_Last_Restart_Reason_Set(BACNET_RESTART_REASON_MAX);
|
||||
zassert_false(status, NULL);
|
||||
zassert_equal(
|
||||
Device_Last_Restart_Reason(),
|
||||
(BACNET_RESTART_REASON)(BACNET_RESTART_REASON_MAX - 1), NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -475,7 +507,8 @@ void test_main(void)
|
||||
{
|
||||
ztest_test_suite(
|
||||
device_tests, ztest_unit_test(testDevice),
|
||||
ztest_unit_test(test_Device_Data_Sharing));
|
||||
ztest_unit_test(test_Device_Data_Sharing),
|
||||
ztest_unit_test(test_Device_Last_Restart_Reason));
|
||||
|
||||
ztest_run_test_suite(device_tests);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user