diff --git a/src/bacnet/basic/object/iv.c b/src/bacnet/basic/object/iv.c index 793e1151..f55cf0a1 100644 --- a/src/bacnet/basic/object/iv.c +++ b/src/bacnet/basic/object/iv.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include /* BACnet Stack defines - first */ #include "bacnet/bacdef.h" @@ -17,21 +19,33 @@ #include "bacnet/bacdcode.h" #include "bacnet/bacapp.h" #include "bacnet/bactext.h" +#include "bacnet/proplist.h" #include "bacnet/basic/object/device.h" #include "bacnet/basic/services.h" /* me! */ #include "bacnet/basic/object/iv.h" +#include "bacnet/basic/sys/keylist.h" +#include "bacnet/basic/sys/debug.h" + +#define PRINTF debug_perror + +/* Key List for storing the object data sorted by instance number */ +static OS_Keylist Object_List = NULL; +/* common object type */ +static const BACNET_OBJECT_TYPE Object_Type = OBJECT_INTEGER_VALUE; -#ifndef MAX_INTEGER_VALUES -#define MAX_INTEGER_VALUES 1 -#endif struct integer_object { bool Out_Of_Service : 1; + bool Changed : 1; int32_t Present_Value; + int32_t Prior_Value; + uint32_t COV_Increment; uint16_t Units; -}; -static struct integer_object Integer_Value[MAX_INTEGER_VALUES]; + uint32_t Instance; + BACNET_CHARACTER_STRING Name; + BACNET_CHARACTER_STRING Description; +} INTERGER_VALUE_DESCR; /* These three arrays are used by the ReadPropertyMultiple handler */ static const int Integer_Value_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, @@ -39,6 +53,8 @@ static const int Integer_Value_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, PROP_UNITS, -1 }; static const int Integer_Value_Properties_Optional[] = { PROP_OUT_OF_SERVICE, + PROP_DESCRIPTION, + PROP_COV_INCREMENT, -1 }; static const int Integer_Value_Properties_Proprietary[] = { -1 }; @@ -70,6 +86,16 @@ void Integer_Value_Property_Lists( return; } +/** + * @brief Gets an object from the list using an instance number as the key + * @param object_instance - object-instance number of the object + * @return object found in the list, or NULL if not found + */ +static struct integer_object *Integer_Value_Object(uint32_t object_instance) +{ + return Keylist_Data(Object_List, object_instance); +} + /** * Determines if a given Integer Value instance is valid * @@ -79,14 +105,9 @@ void Integer_Value_Property_Lists( */ bool Integer_Value_Valid_Instance(uint32_t object_instance) { - unsigned int index; + struct integer_object *pObject = Integer_Value_Object(object_instance); - index = Integer_Value_Instance_To_Index(object_instance); - if (index < MAX_INTEGER_VALUES) { - return true; - } - - return false; + return (pObject != NULL); } /** @@ -96,7 +117,7 @@ bool Integer_Value_Valid_Instance(uint32_t object_instance) */ unsigned Integer_Value_Count(void) { - return MAX_INTEGER_VALUES; + return Keylist_Count(Object_List); } /** @@ -109,7 +130,11 @@ unsigned Integer_Value_Count(void) */ uint32_t Integer_Value_Index_To_Instance(unsigned index) { - return index; + KEY key = UINT32_MAX; + + Keylist_Index_Key(Object_List, index, &key); + + return key; } /** @@ -123,13 +148,7 @@ uint32_t Integer_Value_Index_To_Instance(unsigned index) */ unsigned Integer_Value_Instance_To_Index(uint32_t object_instance) { - unsigned index = MAX_INTEGER_VALUES; - - if (object_instance < MAX_INTEGER_VALUES) { - index = object_instance; - } - - return index; + return Keylist_Index(Object_List, object_instance); } /** @@ -142,16 +161,40 @@ unsigned Integer_Value_Instance_To_Index(uint32_t object_instance) int32_t Integer_Value_Present_Value(uint32_t object_instance) { int32_t value = 0; - unsigned int index; + struct integer_object *pObject = Integer_Value_Object(object_instance); - index = Integer_Value_Instance_To_Index(object_instance); - if (index < MAX_INTEGER_VALUES) { - value = Integer_Value[index].Present_Value; + if (pObject) { + value = pObject->Present_Value; } return value; } +/** + * This function is used to detect a value change, + * using the new value compared against the prior + * value, using a delta as threshold. + * + * This method will update the COV-changed attribute. + * + * @param index Object index + * @param value Given present value. + */ +static void +Integer_Value_COV_Detect(struct integer_object *pObject, int32_t value) +{ + if (pObject) { + int32_t prior_value = pObject->Prior_Value; + uint32_t cov_increment = pObject->COV_Increment; + uint32_t cov_delta = (uint32_t) abs(prior_value - value); + + if (cov_delta >= cov_increment) { + pObject->Changed = true; + pObject->Prior_Value = value; + } + } +} + /** * For a given object instance-number, sets the present-value * @@ -164,12 +207,13 @@ bool Integer_Value_Present_Value_Set( uint32_t object_instance, int32_t value, uint8_t priority) { bool status = false; - unsigned int index; + struct integer_object *pObject = Integer_Value_Object(object_instance); - (void)priority; - index = Integer_Value_Instance_To_Index(object_instance); - if (index < MAX_INTEGER_VALUES) { - Integer_Value[index].Present_Value = value; + (void) priority; + + if (pObject) { + Integer_Value_COV_Detect(pObject, value); + pObject->Present_Value = value; status = true; } @@ -189,15 +233,45 @@ bool Integer_Value_Present_Value_Set( bool Integer_Value_Object_Name( uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { - char text[32] = ""; - unsigned int index; bool status = false; - index = Integer_Value_Instance_To_Index(object_instance); - if (index < MAX_INTEGER_VALUES) { - snprintf(text, sizeof(text), "INTEGER VALUE %lu", - (unsigned long)object_instance); - status = characterstring_init_ansi(object_name, text); + struct integer_object *pObject = Integer_Value_Object(object_instance); + + if (!object_name) { + return false; + } + + if (pObject) { + *object_name = pObject->Name; + status = true; + } + + return status; +} + +/** + * For a given object instance-number, return the description. + * + * Note: the object name must be unique within this device. + * + * @param object_instance - object-instance number of the object + * @param description - description pointer + * + * @return true/false + */ +bool Integer_Value_Description( + uint32_t object_instance, BACNET_CHARACTER_STRING *description) +{ + bool status = false; + struct integer_object *pObject = Integer_Value_Object(object_instance); + + if (!description) { + return false; + } + + if (pObject) { + *description = pObject->Description; + return true; } return status; @@ -210,14 +284,13 @@ bool Integer_Value_Object_Name( * * @return units property value */ -uint16_t Integer_Value_Units(uint32_t instance) +uint16_t Integer_Value_Units(uint32_t object_instance) { - unsigned int index; uint16_t units = UNITS_NO_UNITS; + struct integer_object *pObject = Integer_Value_Object(object_instance); - index = Integer_Value_Instance_To_Index(instance); - if (index < MAX_INTEGER_VALUES) { - units = Integer_Value[index].Units; + if (pObject) { + units = pObject->Units; } return units; @@ -231,14 +304,13 @@ uint16_t Integer_Value_Units(uint32_t instance) * * @return true if the units property value was set */ -bool Integer_Value_Units_Set(uint32_t instance, uint16_t units) +bool Integer_Value_Units_Set(uint32_t object_instance, uint16_t units) { - unsigned int index = 0; bool status = false; + struct integer_object *pObject = Integer_Value_Object(object_instance); - index = Integer_Value_Instance_To_Index(instance); - if (index < MAX_INTEGER_VALUES) { - Integer_Value[index].Units = units; + if (pObject) { + pObject->Units = units; status = true; } @@ -253,14 +325,13 @@ bool Integer_Value_Units_Set(uint32_t instance, uint16_t units) * * @return out-of-service property value */ -bool Integer_Value_Out_Of_Service(uint32_t instance) +bool Integer_Value_Out_Of_Service(uint32_t object_instance) { - unsigned int index = 0; + struct integer_object *pObject = Integer_Value_Object(object_instance); bool value = false; - index = Integer_Value_Instance_To_Index(instance); - if (index < MAX_INTEGER_VALUES) { - value = Integer_Value[index].Out_Of_Service; + if (pObject) { + value = pObject->Out_Of_Service; } return value; @@ -274,13 +345,12 @@ bool Integer_Value_Out_Of_Service(uint32_t instance) * * @return true if the out-of-service property value was set */ -void Integer_Value_Out_Of_Service_Set(uint32_t instance, bool value) +void Integer_Value_Out_Of_Service_Set(uint32_t object_instance, bool value) { - unsigned int index = 0; + struct integer_object *pObject = Integer_Value_Object(object_instance); - index = Integer_Value_Instance_To_Index(instance); - if (index < MAX_INTEGER_VALUES) { - Integer_Value[index].Out_Of_Service = value; + if (pObject) { + pObject->Out_Of_Service = value; } } @@ -313,7 +383,7 @@ int Integer_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: apdu_len = encode_application_object_id( - &apdu[0], OBJECT_INTEGER_VALUE, rpdata->object_instance); + &apdu[0], Object_Type, rpdata->object_instance); break; case PROP_OBJECT_NAME: Integer_Value_Object_Name(rpdata->object_instance, &char_string); @@ -322,7 +392,15 @@ int Integer_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) break; case PROP_OBJECT_TYPE: apdu_len = - encode_application_enumerated(&apdu[0], OBJECT_INTEGER_VALUE); + encode_application_enumerated(&apdu[0], Object_Type); + break; + case PROP_DESCRIPTION: + if (Integer_Value_Description( + rpdata->object_instance, &char_string)) { + apdu_len = + encode_application_character_string(&apdu[0], &char_string); + } + break; case PROP_PRESENT_VALUE: integer_value = @@ -346,6 +424,10 @@ int Integer_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) units = Integer_Value_Units(rpdata->object_instance); apdu_len = encode_application_enumerated(&apdu[0], units); break; + case PROP_COV_INCREMENT: + apdu_len = + encode_application_unsigned(&apdu[0], Integer_Value_COV_Increment(rpdata->object_instance)); + break; default: rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; @@ -406,6 +488,14 @@ bool Integer_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) value.type.Signed_Int, wp_data->priority); } break; + case PROP_COV_INCREMENT: + status = write_property_type_valid( + wp_data, &value, BACNET_APPLICATION_TAG_UNSIGNED_INT); + if (status) { + Integer_Value_COV_Increment_Set( + wp_data->object_instance, value.type.Unsigned_Int); + } + break; case PROP_OUT_OF_SERVICE: status = write_property_type_valid( wp_data, &value, BACNET_APPLICATION_TAG_BOOLEAN); @@ -414,33 +504,208 @@ bool Integer_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) wp_data->object_instance, value.type.Boolean); } break; - case PROP_OBJECT_IDENTIFIER: - case PROP_OBJECT_NAME: - case PROP_OBJECT_TYPE: - case PROP_STATUS_FLAGS: - case PROP_UNITS: - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; - break; default: - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY; + if (property_lists_member( + Integer_Value_Properties_Required, + Integer_Value_Properties_Optional, + Integer_Value_Properties_Proprietary, + wp_data->object_property)) { + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + } else { + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY; + } break; + } return status; } +/** + * @brief For a given object instance-number, determines the COV status + * @param object_instance - object-instance number of the object + * @return true if the COV flag is set + */ +bool Integer_Value_Change_Of_Value(uint32_t object_instance) +{ + bool changed = false; + struct integer_object *pObject = Integer_Value_Object(object_instance); + + if (pObject) { + changed = pObject->Changed; + } + + return changed; +} + +/** + * @brief For a given object instance-number, clears the COV flag + * @param object_instance - object-instance number of the object + */ +void Integer_Value_Change_Of_Value_Clear(uint32_t object_instance) +{ + struct integer_object *pObject = Integer_Value_Object(object_instance); + + if (pObject) { + pObject->Changed = false; + } +} + +/** + * @brief For a given object instance-number, returns the COV-Increment value + * @param object_instance - object-instance number of the object + * @return COV-Increment value + */ +uint32_t Integer_Value_COV_Increment(uint32_t object_instance) +{ + uint32_t value = 0; + struct integer_object *pObject = Integer_Value_Object(object_instance); + + if (pObject) { + value = pObject->COV_Increment; + } + + return value; +} + +/** + * For a given object instance-number, loads the value_list with the COV data. + * + * @param object_instance - object-instance number of the object + * @param value_list - list of COV data + * + * @return true if the value list is encoded + */ +bool Integer_Value_Encode_Value_List( + uint32_t object_instance, BACNET_PROPERTY_VALUE *value_list) +{ + bool status = false; + struct integer_object *pObject = Integer_Value_Object(object_instance); + + if (pObject) { + bool out_of_service = pObject->Out_Of_Service; + uint32_t present_value = pObject->Present_Value; + const bool in_alarm = false; + const bool fault = false; + const bool overridden = false; + + status = cov_value_list_encode_signed_int(value_list, present_value, + in_alarm, fault, overridden, out_of_service); + } + + return status; +} + +/** + * @brief For a given object instance-number, sets the COV-Increment value + * @param object_instance - object-instance number of the object + * @param value - COV-Increment value + */ +void Integer_Value_COV_Increment_Set(uint32_t object_instance, uint32_t value) +{ + struct integer_object *pObject = Integer_Value_Object(object_instance); + + if (pObject) { + pObject->COV_Increment = value; + Integer_Value_COV_Detect(pObject, pObject->Present_Value); + } +} + +/** + * @brief Creates a Integer Value object + * @param object_instance - object-instance number of the object + * @return the object-instance that was created, or BACNET_MAX_INSTANCE + */ +uint32_t Integer_Value_Create(uint32_t object_instance) +{ + struct integer_object *pObject = NULL; + + if (object_instance > BACNET_MAX_INSTANCE) { + return BACNET_MAX_INSTANCE; + } else if (object_instance == BACNET_MAX_INSTANCE) { + /* wildcard instance */ + /* the Object_Identifier property of the newly created object + shall be initialized to a value that is unique within the + responding BACnet-user device. The method used to generate + the object identifier is a local matter.*/ + object_instance = Keylist_Next_Empty_Key(Object_List, 1); + } + pObject = Keylist_Data(Object_List, object_instance); + if (!pObject) { + pObject = calloc(1, sizeof(struct integer_object)); + if (pObject) { + int index = Keylist_Data_Add(Object_List, object_instance, pObject); + + if (index < 0) { + free(pObject); + return BACNET_MAX_INSTANCE; + } + + characterstring_init_ansi(&pObject->Name, ""); + characterstring_init_ansi(&pObject->Description, ""); + pObject->COV_Increment = 1; + pObject->Present_Value = 0; + pObject->Prior_Value = 0; + pObject->Units = UNITS_PERCENT; + pObject->Out_Of_Service = false; + pObject->Changed = false; + + /* add to list */ + } else { + return BACNET_MAX_INSTANCE; + } + } + + return object_instance; +} + +/** + * @brief Deletes an Integer Value object + * @param object_instance - object-instance number of the object + * @return true if the object-instance was deleted + */ +bool Integer_Value_Delete(uint32_t object_instance) +{ + bool status = false; + struct integer_object *pObject = Keylist_Data_Delete(Object_List, object_instance); + + if (pObject) { + free(pObject); + status = true; + } + + return status; +} + +/** + * @brief Deletes all the Integer Values and their data + */ +void Integer_Value_Cleanup(void) +{ + if (Object_List) { + struct integer_object *pObject; + + do { + pObject = Keylist_Data_Pop(Object_List); + if (pObject) { + free(pObject); + } + } while (pObject); + + Keylist_Delete(Object_List); + Object_List = NULL; + } +} + /** * Initializes the Integer Value object data */ void Integer_Value_Init(void) { - unsigned index = 0; - - for (index = 0; index < MAX_INTEGER_VALUES; index++) { - Integer_Value[index].Present_Value = 0; - Integer_Value[index].Out_Of_Service = false; - Integer_Value[index].Units = UNITS_NO_UNITS; + if (!Object_List) { + Object_List = Keylist_Create(); } } + diff --git a/src/bacnet/basic/object/iv.h b/src/bacnet/basic/object/iv.h index f2b1c2d7..38dbd23e 100644 --- a/src/bacnet/basic/object/iv.h +++ b/src/bacnet/basic/object/iv.h @@ -71,16 +71,18 @@ extern "C" { uint32_t object_instance, BACNET_PROPERTY_VALUE * value_list); BACNET_STACK_EXPORT - float Integer_Value_COV_Increment( - uint32_t instance); + uint32_t Integer_Value_COV_Increment( + uint32_t object_instance); BACNET_STACK_EXPORT void Integer_Value_COV_Increment_Set( - uint32_t instance, - float value); + uint32_t object_instance, + uint32_t value); + BACNET_STACK_EXPORT - char *Integer_Value_Description( - uint32_t instance); + bool Integer_Value_Description( + uint32_t object_instance, + BACNET_CHARACTER_STRING *description); BACNET_STACK_EXPORT bool Integer_Value_Description_Set( uint32_t instance, @@ -106,6 +108,19 @@ extern "C" { void Integer_Value_Init( void); + BACNET_STACK_EXPORT + uint32_t Integer_Value_Create( + uint32_t object_instance); + + BACNET_STACK_EXPORT + bool Integer_Value_Delete( + uint32_t object_instance); + + BACNET_STACK_EXPORT + void Integer_Value_Cleanup(void); + + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/bacnet/cov.c b/src/bacnet/cov.c index 03cce9e4..9b513159 100644 --- a/src/bacnet/cov.c +++ b/src/bacnet/cov.c @@ -1038,6 +1038,59 @@ bool cov_value_list_encode_unsigned(BACNET_PROPERTY_VALUE *value_list, return status; } +/** + * @brief Encode the Value List for INT Present-Value and Status-Flags + * @param value_list - #BACNET_PROPERTY_VALUE with at least 2 entries + * @param value - INT present-value + * @param in_alarm - value of in-alarm status-flags + * @param fault - value of in-alarm status-flags + * @param overridden - value of overridden status-flags + * @param out_of_service - value of out-of-service status-flags + * + * @return true if values were encoded + */ +bool cov_value_list_encode_signed_int(BACNET_PROPERTY_VALUE *value_list, + int32_t value, + bool in_alarm, + bool fault, + bool overridden, + bool out_of_service) +{ + bool status = false; + + if (value_list) { + value_list->propertyIdentifier = PROP_PRESENT_VALUE; + value_list->propertyArrayIndex = BACNET_ARRAY_ALL; + value_list->value.context_specific = false; + value_list->value.tag = BACNET_APPLICATION_TAG_SIGNED_INT; + value_list->value.type.Signed_Int = value; + value_list->value.next = NULL; + value_list->priority = BACNET_NO_PRIORITY; + value_list = value_list->next; + } + if (value_list) { + value_list->propertyIdentifier = PROP_STATUS_FLAGS; + value_list->propertyArrayIndex = BACNET_ARRAY_ALL; + value_list->value.context_specific = false; + value_list->value.tag = BACNET_APPLICATION_TAG_BIT_STRING; + bitstring_init(&value_list->value.type.Bit_String); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_IN_ALARM, in_alarm); + bitstring_set_bit( + &value_list->value.type.Bit_String, STATUS_FLAG_FAULT, fault); + bitstring_set_bit(&value_list->value.type.Bit_String, + STATUS_FLAG_OVERRIDDEN, overridden); + bitstring_set_bit(&value_list->value.type.Bit_String, + STATUS_FLAG_OUT_OF_SERVICE, out_of_service); + value_list->value.next = NULL; + value_list->priority = BACNET_NO_PRIORITY; + value_list->next = NULL; + status = true; + } + + return status; +} + #if defined(BACAPP_CHARACTER_STRING) /** * @brief Encode the Value List for CHARACTER_STRING Present-Value and diff --git a/src/bacnet/cov.h b/src/bacnet/cov.h index 10b8f67c..692a0763 100644 --- a/src/bacnet/cov.h +++ b/src/bacnet/cov.h @@ -160,6 +160,13 @@ bool cov_value_list_encode_unsigned(BACNET_PROPERTY_VALUE *value_list, bool overridden, bool out_of_service); BACNET_STACK_EXPORT +bool cov_value_list_encode_signed_int(BACNET_PROPERTY_VALUE *value_list, + int32_t value, + bool in_alarm, + bool fault, + bool overridden, + bool out_of_service); +BACNET_STACK_EXPORT bool cov_value_list_encode_character_string(BACNET_PROPERTY_VALUE *value_list, BACNET_CHARACTER_STRING *value, bool in_alarm, diff --git a/test/bacnet/basic/object/iv/CMakeLists.txt b/test/bacnet/basic/object/iv/CMakeLists.txt index 762e4576..f6197b33 100644 --- a/test/bacnet/basic/object/iv/CMakeLists.txt +++ b/test/bacnet/basic/object/iv/CMakeLists.txt @@ -27,6 +27,7 @@ add_compile_definitions( include_directories( ${SRC_DIR} + ${TST_DIR}/bacnet/basic/object/test ${TST_DIR}/ztest/include ) @@ -44,12 +45,12 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/bacreal.c ${SRC_DIR}/bacnet/bacstr.c ${SRC_DIR}/bacnet/bactext.c - ${SRC_DIR}/bacnet/basic/sys/bigend.c + ${SRC_DIR}/bacnet/cov.c ${SRC_DIR}/bacnet/datetime.c - ${SRC_DIR}/bacnet/basic/sys/days.c ${SRC_DIR}/bacnet/indtext.c ${SRC_DIR}/bacnet/hostnport.c ${SRC_DIR}/bacnet/lighting.c + ${SRC_DIR}/bacnet/proplist.c ${SRC_DIR}/bacnet/timestamp.c ${SRC_DIR}/bacnet/wp.c ${SRC_DIR}/bacnet/weeklyschedule.c @@ -57,8 +58,13 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/dailyschedule.c ${SRC_DIR}/bacnet/calendar_entry.c ${SRC_DIR}/bacnet/special_event.c + ${SRC_DIR}/bacnet/basic/sys/bigend.c + ${SRC_DIR}/bacnet/basic/sys/days.c + ${SRC_DIR}/bacnet/basic/sys/debug.c + ${SRC_DIR}/bacnet/basic/sys/keylist.c # Test and test library files ./src/main.c + ${TST_DIR}/bacnet/basic/object/test/property_test.c ${ZTST_DIR}/ztest_mock.c ${ZTST_DIR}/ztest.c ) diff --git a/test/bacnet/basic/object/iv/src/main.c b/test/bacnet/basic/object/iv/src/main.c index 12c1fd4b..3378183e 100644 --- a/test/bacnet/basic/object/iv/src/main.c +++ b/test/bacnet/basic/object/iv/src/main.c @@ -10,6 +10,7 @@ #include #include #include +#include /** * @addtogroup bacnet_tests @@ -21,74 +22,23 @@ */ static void testInteger_Value(void) { - uint8_t apdu[MAX_APDU] = { 0 }; - int len = 0, test_len = 0; - BACNET_READ_PROPERTY_DATA rpdata = { 0 }; - BACNET_APPLICATION_DATA_VALUE value = { 0 }; - const int *pRequired = NULL; - const int *pOptional = NULL; - const int *pProprietary = NULL; - unsigned count = 0; bool status = false; + unsigned count = 0; + uint32_t object_instance = BACNET_MAX_INSTANCE, test_object_instance = 0; + const int skip_fail_property_list[] = { -1 }; Integer_Value_Init(); + object_instance = Integer_Value_Create(object_instance); count = Integer_Value_Count(); - zassert_true(count > 0, NULL); - rpdata.application_data = &apdu[0]; - rpdata.application_data_len = sizeof(apdu); - rpdata.object_type = OBJECT_INTEGER_VALUE; - rpdata.object_instance = Integer_Value_Index_To_Instance(0); - rpdata.array_index = BACNET_ARRAY_ALL; - status = Integer_Value_Valid_Instance(rpdata.object_instance); + zassert_true(count == 1, NULL); + test_object_instance = Integer_Value_Index_To_Instance(0); + zassert_equal(object_instance, test_object_instance, NULL); + bacnet_object_properties_read_write_test( + OBJECT_INTEGER_VALUE, object_instance, Integer_Value_Property_Lists, + Integer_Value_Read_Property, Integer_Value_Write_Property, + skip_fail_property_list); + status = Integer_Value_Delete(object_instance); zassert_true(status, NULL); - Integer_Value_Property_Lists(&pRequired, &pOptional, &pProprietary); - while ((*pRequired) >= 0) { - rpdata.object_property = *pRequired; - len = Integer_Value_Read_Property(&rpdata); - zassert_true(len >= 0, NULL); - if (len >= 0) { - test_len = bacapp_decode_known_property( - rpdata.application_data, len, &value, rpdata.object_type, - rpdata.object_property); - if (len != test_len) { - printf( - "property '%s': failed to decode!\n", - bactext_property_name(rpdata.object_property)); - } - if (rpdata.object_property == PROP_PRIORITY_ARRAY) { - /* FIXME: known fail to decode */ - len = test_len; - } - zassert_equal(len, test_len, NULL); - } else { - printf( - "property '%s': failed to read!\n", - bactext_property_name(rpdata.object_property)); - } - pRequired++; - } - while ((*pOptional) != -1) { - rpdata.object_property = *pOptional; - rpdata.array_index = BACNET_ARRAY_ALL; - len = Integer_Value_Read_Property(&rpdata); - zassert_not_equal(len, BACNET_STATUS_ERROR, NULL); - if (len > 0) { - test_len = bacapp_decode_application_data( - rpdata.application_data, (uint8_t)rpdata.application_data_len, - &value); - if (len != test_len) { - printf( - "property '%s': failed to decode!\n", - bactext_property_name(rpdata.object_property)); - } - zassert_true(test_len >= 0, NULL); - } else { - printf( - "property '%s': failed to read!\n", - bactext_property_name(rpdata.object_property)); - } - pOptional++; - } } /** * @}