Added getter API function to timer object for state-change-value (#1134)

* Added a new getter API function Timer_State_Change_Value_Get() to the timer object that returns state-change values by copying them to a caller-provided buffer, providing a safer alternative to the existing Timer_State_Change_Value() function which returns a direct pointer to internal data.
This commit is contained in:
Steve Karg
2025-11-10 12:12:23 -06:00
committed by GitHub
parent 28a30be5ec
commit 5574c9d3f1
4 changed files with 77 additions and 19 deletions
+1
View File
@@ -28,6 +28,7 @@ The git repositories are hosted at the following sites:
### Added ### Added
* Added get copy API to timer object for state-change-value (#1134)
* Added Audit Log and Time Value objects to basic device and builds. (#1128) * Added Audit Log and Time Value objects to basic device and builds. (#1128)
* Added ListElement service callback for storing data. (#1128) * Added ListElement service callback for storing data. (#1128)
* Added a basic timer object type example. (#1123) * Added a basic timer object type example. (#1123)
+47 -16
View File
@@ -1012,7 +1012,7 @@ bool Timer_Reliability_Set(uint32_t object_instance, BACNET_RELIABILITY value)
/** /**
* @brief Return the present-value for a specific object instance * @brief Return the present-value for a specific object instance
* @param object_instance [in] BACnet network port object instance number * @param object_instance [in] BACnet object instance number
* @return the present-value for a specific object instance * @return the present-value for a specific object instance
*/ */
uint32_t Timer_Present_Value(uint32_t object_instance) uint32_t Timer_Present_Value(uint32_t object_instance)
@@ -1043,7 +1043,7 @@ uint32_t Timer_Present_Value(uint32_t object_instance)
* is in the EXPIRED or IDLE state, then no transition of the * is in the EXPIRED or IDLE state, then no transition of the
* timer state shall occur. * timer state shall occur.
* *
* @param object_instance [in] BACnet network port object instance number * @param object_instance [in] BACnet object instance number
* @return true if the present-value for a specific object instance was set * @return true if the present-value for a specific object instance was set
*/ */
bool Timer_Present_Value_Set(uint32_t object_instance, uint32_t value) bool Timer_Present_Value_Set(uint32_t object_instance, uint32_t value)
@@ -1120,7 +1120,7 @@ bool Timer_Present_Value_Set(uint32_t object_instance, uint32_t value)
/** /**
* @brief Get the update-time property value for the object-instance specified * @brief Get the update-time property value for the object-instance specified
* @param object_instance [in] BACnet network port object instance number * @param object_instance [in] BACnet object instance number
* @return true if property value was retrieved * @return true if property value was retrieved
*/ */
bool Timer_Update_Time(uint32_t object_instance, BACNET_DATE_TIME *bdatetime) bool Timer_Update_Time(uint32_t object_instance, BACNET_DATE_TIME *bdatetime)
@@ -1139,7 +1139,7 @@ bool Timer_Update_Time(uint32_t object_instance, BACNET_DATE_TIME *bdatetime)
/** /**
* @brief Get the update-time property value for the object-instance specified * @brief Get the update-time property value for the object-instance specified
* @param object_instance [in] BACnet network port object instance number * @param object_instance [in] BACnet object instance number
* @return true if property value was retrieved * @return true if property value was retrieved
*/ */
bool Timer_Update_Time_Set( bool Timer_Update_Time_Set(
@@ -1163,7 +1163,7 @@ bool Timer_Update_Time_Set(
* @details The Expiration_Time property shall indicate the date and time * @details The Expiration_Time property shall indicate the date and time
* when the timer will expire. The value of Expiration_Time * when the timer will expire. The value of Expiration_Time
* shall be calculated at the time the property is read. * shall be calculated at the time the property is read.
* @param object_instance [in] BACnet network port object instance number * @param object_instance [in] BACnet object instance number
* @param bdatetime [out] the property value retrieved * @param bdatetime [out] the property value retrieved
* @return true if property value was retrieved * @return true if property value was retrieved
*/ */
@@ -1432,7 +1432,7 @@ bool Timer_Priority_For_Writing_Set(uint32_t object_instance, uint8_t value)
* The array index of the element is equal to the numerical value of the * The array index of the element is equal to the numerical value of the
* BACnetTimerTransition enumeration for the respective timer state change. * BACnetTimerTransition enumeration for the respective timer state change.
* The timer state change NONE has no corresponding array element. * The timer state change NONE has no corresponding array element.
* @param object_instance [in] BACnet network port object instance number * @param object_instance [in] BACnet object instance number
* @param index [in] array index requested: * @param index [in] array index requested:
* 0 to N for individual array members * 0 to N for individual array members
* @param apdu [out] Buffer in which the APDU contents are built, or NULL to * @param apdu [out] Buffer in which the APDU contents are built, or NULL to
@@ -1461,7 +1461,7 @@ static int Timer_State_Change_Value_Encode(
/** /**
* @brief Get the state-change value array element value * @brief Get the state-change value array element value
* @param object_instance - BACnet network port object instance number * @param object_instance - BACnet object instance number
* @param transition - the state-change enumeration requested * @param transition - the state-change enumeration requested
* @return state-change structure or NULL if transition is out of range. * @return state-change structure or NULL if transition is out of range.
*/ */
@@ -1487,11 +1487,42 @@ BACNET_TIMER_STATE_CHANGE_VALUE *Timer_State_Change_Value(
} }
/** /**
* @brief Set the state-change value array element value * @brief Get the state-change value array element value
* @param object_instance - BACnet network port object instance number * @param object_instance - BACnet object instance number
* @param transition - the state-change enumeration requested * @param transition - the state-change enumeration requested
* @param value state-change structure values * @param value - [out] state-change structure where value will be copied
* @return true if the transition is in range and values were copied * @return true if the transition is in range and value was copied
*/
bool Timer_State_Change_Value_Get(
uint32_t object_instance,
BACNET_TIMER_TRANSITION transition,
BACNET_TIMER_STATE_CHANGE_VALUE *value)
{
bool status = false;
unsigned index;
struct object_data *pObject;
pObject = Keylist_Data(Object_List, object_instance);
if (pObject) {
/* Note: The timer state change NONE=0
has no corresponding array element.*/
if ((transition != TIMER_TRANSITION_NONE) &&
(transition < TIMER_TRANSITION_MAX)) {
index = transition - 1;
status = bacnet_timer_value_copy(
value, &pObject->State_Change_Values[index]);
}
}
return status;
}
/**
* @brief Set the state-change value array element value
* @param object_instance - BACnet object instance number
* @param transition - the state-change enumeration requested
* @param value - state-change structure values
* @return true if the transition is in range and value was copied
*/ */
bool Timer_State_Change_Value_Set( bool Timer_State_Change_Value_Set(
uint32_t object_instance, uint32_t object_instance,
@@ -1669,7 +1700,7 @@ int Timer_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
/** /**
* @brief Decode a BACnetARRAY property element to determine the element length * @brief Decode a BACnetARRAY property element to determine the element length
* @param object_instance [in] BACnet network port object instance number * @param object_instance [in] BACnet object instance number
* @param apdu [in] Buffer in which the APDU contents are extracted * @param apdu [in] Buffer in which the APDU contents are extracted
* @param apdu_size [in] The size of the APDU buffer * @param apdu_size [in] The size of the APDU buffer
* @return The length of the decoded apdu, or BACNET_STATUS_ERROR on error * @return The length of the decoded apdu, or BACNET_STATUS_ERROR on error
@@ -1689,7 +1720,7 @@ static int Timer_State_Change_Value_Length(
/** /**
* @brief Write a value to a BACnetARRAY property element value * @brief Write a value to a BACnetARRAY property element value
* using a BACnetARRAY write utility function * using a BACnetARRAY write utility function
* @param object_instance [in] BACnet network port object instance number * @param object_instance [in] BACnet object instance number
* @param array_index [in] array index to write: * @param array_index [in] array index to write:
* 0=array size, 1 to N for individual array members * 0=array size, 1 to N for individual array members
* @param application_data [in] encoded element value * @param application_data [in] encoded element value
@@ -1734,7 +1765,7 @@ static BACNET_ERROR_CODE Timer_State_Change_Value_Write(
/** /**
* @brief Decode a BACnetLIST property element to determine the element length * @brief Decode a BACnetLIST property element to determine the element length
* @param object_instance [in] BACnet network port object instance number * @param object_instance [in] BACnet object instance number
* @param apdu [in] Buffer in which the APDU contents are extracted * @param apdu [in] Buffer in which the APDU contents are extracted
* @param apdu_size [in] The size of the APDU buffer * @param apdu_size [in] The size of the APDU buffer
* @return The length of the decoded apdu, or BACNET_STATUS_ERROR on error * @return The length of the decoded apdu, or BACNET_STATUS_ERROR on error
@@ -1756,7 +1787,7 @@ static int Timer_List_Of_Object_Property_References_Length(
/** /**
* @brief Add an element to a BACnetLIST property * @brief Add an element to a BACnetLIST property
* using a BACnetLIST add utility function * using a BACnetLIST add utility function
* @param object_instance [in] BACnet network port object instance number * @param object_instance [in] BACnet object instance number
* @param application_data [in] encoded element value * @param application_data [in] encoded element value
* @param application_data_len [in] The size of the encoded element value * @param application_data_len [in] The size of the encoded element value
* @return BACNET_ERROR_CODE value or ERROR_CODE_SUCCESS * @return BACNET_ERROR_CODE value or ERROR_CODE_SUCCESS
@@ -1801,7 +1832,7 @@ static BACNET_ERROR_CODE Timer_List_Of_Object_Property_References_Add(
/** /**
* @brief Remove an element from a BACnetLIST property * @brief Remove an element from a BACnetLIST property
* @param object_instance [in] BACnet network port object instance number * @param object_instance [in] BACnet object instance number
* @param application_data [in] encoded element value * @param application_data [in] encoded element value
* @param application_data_len [in] The size of the encoded element value * @param application_data_len [in] The size of the encoded element value
* @return BACNET_ERROR_CODE value or ERROR_CODE_SUCCESS * @return BACNET_ERROR_CODE value or ERROR_CODE_SUCCESS
+5
View File
@@ -149,6 +149,11 @@ BACNET_STACK_EXPORT
BACNET_TIMER_STATE_CHANGE_VALUE *Timer_State_Change_Value( BACNET_TIMER_STATE_CHANGE_VALUE *Timer_State_Change_Value(
uint32_t object_instance, BACNET_TIMER_TRANSITION transition); uint32_t object_instance, BACNET_TIMER_TRANSITION transition);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
bool Timer_State_Change_Value_Get(
uint32_t object_instance,
BACNET_TIMER_TRANSITION transition,
BACNET_TIMER_STATE_CHANGE_VALUE *value);
BACNET_STACK_EXPORT
bool Timer_State_Change_Value_Set( bool Timer_State_Change_Value_Set(
uint32_t object_instance, uint32_t object_instance,
BACNET_TIMER_TRANSITION transition, BACNET_TIMER_TRANSITION transition,
+24 -3
View File
@@ -559,7 +559,9 @@ static void test_Timer_Operation(void)
bool status = false; bool status = false;
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE member = { 0 }; BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE member = { 0 };
BACNET_TIMER_STATE_CHANGE_VALUE *value = NULL; BACNET_TIMER_STATE_CHANGE_VALUE *value = NULL;
BACNET_TIMER_STATE_CHANGE_VALUE state_change_value = { 0 };
BACNET_TIMER_STATE test_state = TIMER_STATE_IDLE; BACNET_TIMER_STATE test_state = TIMER_STATE_IDLE;
BACNET_TIMER_TRANSITION transition;
BACNET_DATE_TIME bdatetime = { 0 }; BACNET_DATE_TIME bdatetime = { 0 };
uint32_t elapsed_time = 0; uint32_t elapsed_time = 0;
unsigned members = 0, i = 0; unsigned members = 0, i = 0;
@@ -615,9 +617,28 @@ static void test_Timer_Operation(void)
value->tag = BACNET_APPLICATION_TAG_ENUMERATED; value->tag = BACNET_APPLICATION_TAG_ENUMERATED;
value->type.Enumerated = BINARY_ACTIVE; value->type.Enumerated = BINARY_ACTIVE;
/* alternate API */ /* alternate API */
status = Timer_State_Change_Value_Set( transition = TIMER_TRANSITION_NONE;
instance, TIMER_TRANSITION_EXPIRED_TO_RUNNING, value); while (transition != TIMER_TRANSITION_MAX) {
zassert_true(status, NULL); status = Timer_State_Change_Value_Get(
instance, transition, &state_change_value);
if (transition == TIMER_TRANSITION_NONE) {
zassert_false(status, NULL);
} else {
zassert_true(
status, "transition=%s",
bactext_timer_transition_name(transition));
}
status = Timer_State_Change_Value_Set(
instance, transition, &state_change_value);
if (transition == TIMER_TRANSITION_NONE) {
zassert_false(status, NULL);
} else {
zassert_true(
status, "transition=%s",
bactext_timer_transition_name(transition));
}
transition++;
}
/* start timer using a write to timer-running property to use defaults */ /* start timer using a write to timer-running property to use defaults */
/* IDLE_TO_RUNNING */ /* IDLE_TO_RUNNING */
status = Timer_State_Set(instance, TIMER_STATE_IDLE); status = Timer_State_Set(instance, TIMER_STATE_IDLE);