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
|
compilers will allocate adequate sized datatype for enum
|
||||||
which is used to store decoding */
|
which is used to store decoding */
|
||||||
RESTART_REASON_PROPRIETARY_MIN = 64,
|
RESTART_REASON_PROPRIETARY_MIN = 64,
|
||||||
RESTART_REASON_PROPRIETARY_MAX = 255
|
RESTART_REASON_PROPRIETARY_MAX = 255,
|
||||||
|
BACNET_RESTART_REASON_MAX = 256
|
||||||
} BACNET_RESTART_REASON;
|
} BACNET_RESTART_REASON;
|
||||||
|
|
||||||
typedef enum BACnetPropertyStates {
|
typedef enum BACnetPropertyStates {
|
||||||
|
|||||||
@@ -1279,6 +1279,7 @@ static const int32_t Device_Properties_Optional[] = {
|
|||||||
PROP_ACTIVE_COV_SUBSCRIPTIONS,
|
PROP_ACTIVE_COV_SUBSCRIPTIONS,
|
||||||
PROP_SERIAL_NUMBER,
|
PROP_SERIAL_NUMBER,
|
||||||
PROP_TIME_OF_DEVICE_RESTART,
|
PROP_TIME_OF_DEVICE_RESTART,
|
||||||
|
PROP_LAST_RESTART_REASON,
|
||||||
#if defined(BACNET_TIME_MASTER)
|
#if defined(BACNET_TIME_MASTER)
|
||||||
PROP_TIME_SYNCHRONIZATION_RECIPIENTS,
|
PROP_TIME_SYNCHRONIZATION_RECIPIENTS,
|
||||||
PROP_TIME_SYNCHRONIZATION_INTERVAL,
|
PROP_TIME_SYNCHRONIZATION_INTERVAL,
|
||||||
@@ -1331,7 +1332,10 @@ static const int32_t Writable_Properties[] = {
|
|||||||
PROP_BACKUP_PREPARATION_TIME,
|
PROP_BACKUP_PREPARATION_TIME,
|
||||||
PROP_RESTORE_PREPARATION_TIME,
|
PROP_RESTORE_PREPARATION_TIME,
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(BACAPP_TIMESTAMP)
|
||||||
PROP_TIME_OF_DEVICE_RESTART,
|
PROP_TIME_OF_DEVICE_RESTART,
|
||||||
|
#endif
|
||||||
|
PROP_LAST_RESTART_REASON,
|
||||||
-1
|
-1
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1434,6 +1438,7 @@ static uint8_t Device_UUID[16];
|
|||||||
/* static uint8_t Max_Segments_Accepted = 0; */
|
/* static uint8_t Max_Segments_Accepted = 0; */
|
||||||
/* VT_Classes_Supported */
|
/* VT_Classes_Supported */
|
||||||
/* Active_VT_Sessions */
|
/* Active_VT_Sessions */
|
||||||
|
static BACNET_RESTART_REASON Last_Restart_Reason = RESTART_REASON_UNKNOWN;
|
||||||
static BACNET_TIMESTAMP Time_Of_Device_Restart;
|
static BACNET_TIMESTAMP Time_Of_Device_Restart;
|
||||||
static BACNET_TIME Local_Time; /* rely on OS, if there is one */
|
static BACNET_TIME Local_Time; /* rely on OS, if there is one */
|
||||||
static BACNET_DATE Local_Date; /* 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;
|
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)
|
void Device_Time_Of_Restart(BACNET_TIMESTAMP *time_of_restart)
|
||||||
{
|
{
|
||||||
bacapp_timestamp_copy(time_of_restart, &Time_Of_Device_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;
|
(void)object_instance;
|
||||||
if (array_index == 0) {
|
if (array_index == 0) {
|
||||||
/* This array is not required to be resizable
|
/* This array is not required to be resizable
|
||||||
through BACnet write services */
|
through BACnet write services */
|
||||||
(void)array_size;
|
(void)array_size;
|
||||||
error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||||
} else {
|
} else if (array_index <= BACNET_BACKUP_FILE_COUNT) {
|
||||||
len = bacnet_object_id_application_decode(
|
len = bacnet_object_id_application_decode(
|
||||||
application_data, application_data_len, &object_type, &instance);
|
application_data, application_data_len, &object_type, &instance);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
@@ -2579,6 +2611,8 @@ static BACNET_ERROR_CODE Device_Configuration_File_Write(
|
|||||||
} else {
|
} else {
|
||||||
error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
return error_code;
|
return error_code;
|
||||||
@@ -2979,6 +3013,10 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
|||||||
apdu_len =
|
apdu_len =
|
||||||
bacapp_encode_timestamp(&apdu[0], &Time_Of_Device_Restart);
|
bacapp_encode_timestamp(&apdu[0], &Time_Of_Device_Restart);
|
||||||
break;
|
break;
|
||||||
|
case PROP_LAST_RESTART_REASON:
|
||||||
|
apdu_len =
|
||||||
|
encode_application_enumerated(&apdu[0], Last_Restart_Reason);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||||
rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||||
@@ -3351,14 +3389,26 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(BACAPP_TIMESTAMP)
|
||||||
case PROP_TIME_OF_DEVICE_RESTART:
|
case PROP_TIME_OF_DEVICE_RESTART:
|
||||||
status = write_property_type_valid(
|
status = write_property_type_valid(
|
||||||
wp_data, &value, BACNET_APPLICATION_TAG_TIMESTAMP);
|
wp_data, &value, BACNET_APPLICATION_TAG_TIMESTAMP);
|
||||||
if (status) {
|
if (status) {
|
||||||
#if defined(BACAPP_TIMESTAMP)
|
|
||||||
bacapp_timestamp_copy(
|
bacapp_timestamp_copy(
|
||||||
&Time_Of_Device_Restart, &value.type.Time_Stamp);
|
&Time_Of_Device_Restart, &value.type.Time_Stamp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
#endif
|
#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;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -417,6 +417,11 @@ const char *Device_Serial_Number(void);
|
|||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
bool Device_Serial_Number_Set(const char *name, size_t length);
|
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
|
BACNET_STACK_EXPORT
|
||||||
void Device_Time_Of_Restart(BACNET_TIMESTAMP *time_of_restart);
|
void Device_Time_Of_Restart(BACNET_TIMESTAMP *time_of_restart);
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
|
|||||||
@@ -1215,6 +1215,7 @@ static const int32_t Device_Properties_Optional[] = {
|
|||||||
#endif
|
#endif
|
||||||
PROP_SERIAL_NUMBER,
|
PROP_SERIAL_NUMBER,
|
||||||
PROP_TIME_OF_DEVICE_RESTART,
|
PROP_TIME_OF_DEVICE_RESTART,
|
||||||
|
PROP_LAST_RESTART_REASON,
|
||||||
#if defined(BACNET_TIME_MASTER)
|
#if defined(BACNET_TIME_MASTER)
|
||||||
PROP_TIME_SYNCHRONIZATION_RECIPIENTS,
|
PROP_TIME_SYNCHRONIZATION_RECIPIENTS,
|
||||||
PROP_TIME_SYNCHRONIZATION_INTERVAL,
|
PROP_TIME_SYNCHRONIZATION_INTERVAL,
|
||||||
@@ -1268,6 +1269,7 @@ static const int32_t Writable_Properties[] = {
|
|||||||
PROP_RESTORE_PREPARATION_TIME,
|
PROP_RESTORE_PREPARATION_TIME,
|
||||||
#endif
|
#endif
|
||||||
PROP_TIME_OF_DEVICE_RESTART,
|
PROP_TIME_OF_DEVICE_RESTART,
|
||||||
|
PROP_LAST_RESTART_REASON,
|
||||||
-1
|
-1
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1368,6 +1370,7 @@ static list_element_function Device_Add_List_Element_Callback;
|
|||||||
static list_element_function Device_Remove_List_Element_Callback;
|
static list_element_function Device_Remove_List_Element_Callback;
|
||||||
static uint8_t Device_UUID[16];
|
static uint8_t Device_UUID[16];
|
||||||
static const char *Serial_Number = BACNET_DEVICE_SERIAL_NUMBER;
|
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_TIMESTAMP Time_Of_Device_Restart;
|
||||||
static BACNET_TIME Local_Time; /* rely on OS, if there is one */
|
static BACNET_TIME Local_Time; /* rely on OS, if there is one */
|
||||||
static BACNET_DATE Local_Date; /* 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;
|
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)
|
void Device_Time_Of_Restart(BACNET_TIMESTAMP *time_of_restart)
|
||||||
{
|
{
|
||||||
bacapp_timestamp_copy(time_of_restart, &Time_Of_Device_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 =
|
apdu_len =
|
||||||
bacapp_encode_timestamp(&apdu[0], &Time_Of_Device_Restart);
|
bacapp_encode_timestamp(&apdu[0], &Time_Of_Device_Restart);
|
||||||
break;
|
break;
|
||||||
|
case PROP_LAST_RESTART_REASON:
|
||||||
|
apdu_len =
|
||||||
|
encode_application_enumerated(&apdu[0], Last_Restart_Reason);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||||
rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||||
@@ -3225,6 +3259,18 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
if (property_lists_member(
|
if (property_lists_member(
|
||||||
Device_Properties_Required, Device_Properties_Optional,
|
Device_Properties_Required, Device_Properties_Optional,
|
||||||
|
|||||||
@@ -464,6 +464,38 @@ static void testDevice(void)
|
|||||||
zassert_true(property_list.Required.count > 0, NULL);
|
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(
|
ztest_test_suite(
|
||||||
device_tests, ztest_unit_test(testDevice),
|
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);
|
ztest_run_test_suite(device_tests);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user