Added basic timer object, internal state machine, and unit tests (#1123)

* Added basic timer object, internal state machine, and unit tests

* Added BACnetTimerStateChangeValue encode, decode, parse, print, and diff with unit tests

* Changed handler of add/remove list element to check if the property is a BACnetLIST

* Added BACnetLIST utility for handling WriteProperty to a list.

* Fixed outlier ReadProperty object handlers to return zero when the RP parameter is NULL.
This commit is contained in:
Steve Karg
2025-11-05 15:11:45 -06:00
committed by GitHub
parent 17259b37f3
commit 4dd13cf199
126 changed files with 5509 additions and 56 deletions
+45 -4
View File
@@ -53,6 +53,7 @@
#include "bacnet/basic/object/csv.h"
#include "bacnet/basic/object/iv.h"
#include "bacnet/basic/object/time_value.h"
#include "bacnet/basic/object/timer.h"
#include "bacnet/basic/object/channel.h"
#include "bacnet/basic/object/program.h"
#include "bacnet/basic/object/lo.h"
@@ -129,6 +130,7 @@
defined(CONFIG_BACNET_BASIC_OBJECT_FILE) || \
defined(CONFIG_BACNET_BASIC_OBJECT_STRUCTURED_VIEW) || \
defined(CONFIG_BACNET_BASIC_OBJECT_BITSTRING_VALUE) || \
defined(CONFIG_BACNET_BASIC_OBJECT_TIMER) || \
defined(CONFIG_BACNET_BASIC_OBJECT_PROGRAM) || \
defined(CONFIG_BACNET_BASIC_OBJECT_CHARACTERSTRING_VALUE))
#define CONFIG_BACNET_BASIC_OBJECT_ALL
@@ -158,6 +160,7 @@
#define CONFIG_BACNET_BASIC_OBJECT_FILE
#define CONFIG_BACNET_BASIC_OBJECT_STRUCTURED_VIEW
#define CONFIG_BACNET_BASIC_OBJECT_BITSTRING_VALUE
#define CONFIG_BACNET_BASIC_OBJECT_TIMER
#define CONFIG_BACNET_BASIC_OBJECT_PROGRAM
#define CONFIG_BACNET_BASIC_OBJECT_CHARACTERSTRING_VALUE
#endif
@@ -185,6 +188,10 @@
#undef CONFIG_BACNET_BASIC_OBJECT_NETWORK_PORT
#warning "Network Port is configured, but BACnet Protocol Revision < 17"
#endif
#ifdef CONFIG_BACNET_BASIC_OBJECT_TIMER
#undef CONFIG_BACNET_BASIC_OBJECT_TIMER
#warning "Timer is configured, but BACnet Protocol Revision < 17"
#endif
#endif
#if (BACNET_PROTOCOL_REVISION < 24)
@@ -750,6 +757,28 @@ static object_functions_t My_Object_Table[] = {
CharacterString_Value_Delete,
NULL /* Timer */ },
#endif
#if defined(CONFIG_BACNET_BASIC_OBJECT_TIMER)
{ OBJECT_TIMER,
Timer_Init,
Timer_Count,
Timer_Index_To_Instance,
Timer_Valid_Instance,
Timer_Object_Name,
Timer_Read_Property,
Timer_Write_Property,
Timer_Property_Lists,
NULL /* ReadRangeInfo */,
NULL /* Iterator */,
NULL /* Value_Lists */,
NULL /* COV */,
NULL /* COV Clear */,
NULL /* Intrinsic Reporting */,
Timer_Add_List_Element,
Timer_Remove_List_Element,
Timer_Create,
Timer_Delete,
Timer_Task },
#endif
#if defined(CONFIG_BACNET_BASIC_OBJECT_PROGRAM)
{ OBJECT_BITSTRING_VALUE,
Program_Init,
@@ -1783,8 +1812,16 @@ uint32_t Device_Interval_Offset(void)
}
#endif
/* return the length of the apdu encoded or BACNET_STATUS_ERROR for error or
BACNET_STATUS_ABORT for abort message */
/**
* ReadProperty handler for this object. For the given ReadProperty
* data, the application_data is loaded or the error flags are set.
*
* @param rpdata - BACNET_READ_PROPERTY_DATA data, including
* requested data and space for the reply, or error response.
*
* @return number of APDU bytes in the response, zero if no data, or
* BACNET_STATUS_ERROR on error.
*/
int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = 0; /* return value */
@@ -2007,7 +2044,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
* @param pObject - object table
* @param rpdata [in,out] Structure with the requested Object & Property info
* on entry, and APDU message on return.
* @return The length of the APDU on success, else BACNET_STATUS_ERROR
* @return number of APDU bytes in the response, zero if no data, or
* BACNET_STATUS_ERROR on error.
*/
static int Read_Property_Common(
const struct object_functions *pObject, BACNET_READ_PROPERTY_DATA *rpdata)
@@ -2019,7 +2057,7 @@ static int Read_Property_Common(
struct special_property_list_t property_list;
#endif
if ((rpdata->application_data == NULL) ||
if ((rpdata == NULL) || (rpdata->application_data == NULL) ||
(rpdata->application_data_len == 0)) {
return 0;
}
@@ -2061,6 +2099,9 @@ int Device_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
int apdu_len = BACNET_STATUS_ERROR;
struct object_functions *pObject = NULL;
if (!rpdata) {
return 0;
}
/* initialize the default return values */
rpdata->error_class = ERROR_CLASS_OBJECT;
rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT;