diff --git a/src/bacnet/basic/object/csv.c b/src/bacnet/basic/object/csv.c index 4af7d090..e2c55722 100644 --- a/src/bacnet/basic/object/csv.c +++ b/src/bacnet/basic/object/csv.c @@ -29,13 +29,15 @@ static const BACNET_OBJECT_TYPE Object_Type = OBJECT_CHARACTERSTRING_VALUE; /* These three arrays are used by the ReadPropertyMultiple handler */ static const int Properties_Required[] = { + /* list of the required properties */ PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, -1 }; -static const int Properties_Optional[] = { PROP_EVENT_STATE, - PROP_OUT_OF_SERVICE, - PROP_DESCRIPTION, -1 }; +static const int Properties_Optional[] = { + /* list of the optional properties */ + PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_DESCRIPTION, -1 +}; static const int Properties_Proprietary[] = { -1 }; @@ -47,8 +49,8 @@ typedef struct characterstring_object { /* Here is our Present Value */ BACNET_CHARACTER_STRING Present_Value_Backup; BACNET_CHARACTER_STRING Present_Value; - BACNET_CHARACTER_STRING Name; - BACNET_CHARACTER_STRING Description; + const char *Object_Name; + const char *Description; } CHARACTERSTRING_VALUE_DESCR; /** @@ -100,14 +102,12 @@ uint32_t CharacterString_Value_Create(uint32_t object_instance) if (pObject) { /* add to list */ 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->Object_Name = NULL; + pObject->Description = NULL; characterstring_init_ansi(&pObject->Present_Value, ""); characterstring_init_ansi(&pObject->Present_Value_Backup, ""); pObject->Out_Of_Service = false; @@ -339,8 +339,8 @@ bool CharacterString_Value_Out_Of_Service(uint32_t object_instance) * @param object_instance - object-instance number of the object * @param true/false */ -static void -CharacterString_Value_Out_Of_Service_Set(uint32_t object_instance, bool value) +void CharacterString_Value_Out_Of_Service_Set( + uint32_t object_instance, bool value) { struct characterstring_object *pObject = CharacterString_Value_Object(object_instance); @@ -423,115 +423,116 @@ bool CharacterString_Value_Encode_Value_List( } /** - * For a given object instance-number, return the description. - * + * @brief For a given object instance-number, returns the description * @param object_instance - object-instance number of the object - * - * @return C-string pointer to the description. + * @return description text or NULL if not found */ -bool CharacterString_Value_Description( - uint32_t object_instance, BACNET_CHARACTER_STRING *description) +const char *CharacterString_Value_Description(uint32_t object_instance) { - bool status = false; - struct characterstring_object *pObject = - CharacterString_Value_Object(object_instance); - - if (!description) { - return false; - } + const char *name = NULL; + const struct characterstring_object *pObject; + pObject = CharacterString_Value_Object(object_instance); if (pObject) { - *description = pObject->Description; - status = true; - } - - return status; -} - -/** - * For a given object instance-number, set the description text. - * - * @param object_instance - object-instance number of the object - * @param new_descr - C-String pointer to the string, representing the - * description text - * - * @return True on success, false otherwise. - */ -bool CharacterString_Value_Description_Set( - uint32_t object_instance, const char *new_descr) -{ - bool status = false; /* return value */ - struct characterstring_object *pObject = - CharacterString_Value_Object(object_instance); - - if (pObject) { - if (new_descr) { - status = - characterstring_init_ansi(&pObject->Description, new_descr); + if (pObject->Description == NULL) { + name = ""; } else { - status = characterstring_init_ansi(&pObject->Description, ""); + name = pObject->Description; } } + return name; +} + +/** + * @brief For a given object instance-number, sets the description + * @param object_instance - object-instance number of the object + * @param new_name - holds the description to be set + * @return true if object-name was set + */ +bool CharacterString_Value_Description_Set( + uint32_t object_instance, const char *new_name) +{ + bool status = false; /* return value */ + struct characterstring_object *pObject; + + pObject = CharacterString_Value_Object(object_instance); + if (pObject) { + status = true; + pObject->Description = new_name; + } + return status; } /** - * For a given object instance-number, return the object text. - * + * @brief Get the object name * @param object_instance - object-instance number of the object - * @param object_name - Pointer to the BACnet string object that shall take the - * object name - * - * @return True on success, false otherwise. + * @param object_name - holds the object-name to be retrieved + * @return true if object-name was retrieved */ bool CharacterString_Value_Object_Name( uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) { - struct characterstring_object *pObject = - CharacterString_Value_Object(object_instance); + char text[64] = ""; bool status = false; + struct characterstring_object *pObject; - if (!object_name) { - return false; - } - + pObject = CharacterString_Value_Object(object_instance); if (pObject) { - *object_name = pObject->Name; - status = true; + if (pObject->Object_Name == NULL) { + snprintf( + text, sizeof(text), "CHARACTER STRING VALUE %lu", + (unsigned long)object_instance); + status = characterstring_init_ansi(object_name, text); + } else { + status = + characterstring_init_ansi(object_name, pObject->Object_Name); + } } return status; } /** - * For a given object instance-number, set the object text. - * - * Note: the object name must be unique within this device - * + * @brief For a given object instance-number, sets the object-name * @param object_instance - object-instance number of the object - * @param new_name - C-String pointer to the text, representing the object name - * - * @return True on success, false otherwise. + * @param new_name - holds the object-name to be set + * @return true if object-name was set */ bool CharacterString_Value_Name_Set( uint32_t object_instance, const char *new_name) { - bool status = false; /* return value */ - struct characterstring_object *pObject = - CharacterString_Value_Object(object_instance); + bool status = false; + struct characterstring_object *pObject; + pObject = CharacterString_Value_Object(object_instance); if (pObject) { - if (new_name) { - status = characterstring_init_ansi(&pObject->Name, new_name); - } else { - status = characterstring_init_ansi(&pObject->Name, ""); - } + status = true; + pObject->Object_Name = new_name; } return status; } +/** + * @brief Return the object name C string + * @param object_instance [in] BACnet object instance number + * @return object name or NULL if not found + */ +const char *CharacterString_Value_Name_ASCII(uint32_t object_instance) +{ + const char *name = NULL; + struct characterstring_object *pObject; + + pObject = CharacterString_Value_Object(object_instance); + if (pObject) { + name = pObject->Object_Name; + } + + return name; +} + /** * Return the requested property of the character string value. * @@ -556,7 +557,6 @@ int CharacterString_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) (rpdata->application_data_len == 0)) { return 0; } - pObject = CharacterString_Value_Object(rpdata->object_instance); /* Valid object? */ if (!pObject) { @@ -564,9 +564,7 @@ int CharacterString_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT; return BACNET_STATUS_ERROR; } - apdu = rpdata->application_data; - switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: apdu_len = encode_application_object_id( @@ -582,11 +580,11 @@ int CharacterString_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) } break; case PROP_DESCRIPTION: - if (CharacterString_Value_Description( - rpdata->object_instance, &char_string)) { - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - } + characterstring_init_ansi( + &char_string, + CharacterString_Value_Description(rpdata->object_instance)); + apdu_len = + encode_application_character_string(&apdu[0], &char_string); break; case PROP_OBJECT_TYPE: apdu_len = encode_application_enumerated( @@ -702,18 +700,16 @@ bool CharacterString_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_DESCRIPTION: - case PROP_OBJECT_TYPE: - case PROP_STATUS_FLAGS: - case PROP_EVENT_STATE: - 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( + Properties_Required, Properties_Optional, + 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; } diff --git a/src/bacnet/basic/object/csv.h b/src/bacnet/basic/object/csv.h index 11529e38..0c301b15 100644 --- a/src/bacnet/basic/object/csv.h +++ b/src/bacnet/basic/object/csv.h @@ -55,6 +55,8 @@ bool CharacterString_Value_Object_Name( BACNET_STACK_EXPORT bool CharacterString_Value_Name_Set( uint32_t object_instance, const char *new_name); +BACNET_STACK_EXPORT +const char *CharacterString_Value_Name_ASCII(uint32_t object_instance); BACNET_STACK_EXPORT bool CharacterString_Value_Present_Value( @@ -62,11 +64,18 @@ bool CharacterString_Value_Present_Value( BACNET_STACK_EXPORT bool CharacterString_Value_Present_Value_Set( uint32_t object_instance, const BACNET_CHARACTER_STRING *value); + +BACNET_STACK_EXPORT +const char *CharacterString_Value_Description(uint32_t object_instance); BACNET_STACK_EXPORT bool CharacterString_Value_Description_Set( uint32_t object_instance, const char *new_descr); + BACNET_STACK_EXPORT bool CharacterString_Value_Out_Of_Service(uint32_t object_instance); +BACNET_STACK_EXPORT +void CharacterString_Value_Out_Of_Service_Set( + uint32_t object_instance, bool value); BACNET_STACK_EXPORT bool CharacterString_Value_Change_Of_Value(uint32_t instance); diff --git a/test/bacnet/basic/object/csv/CMakeLists.txt b/test/bacnet/basic/object/csv/CMakeLists.txt index 6eb24c73..8e32aa60 100644 --- a/test/bacnet/basic/object/csv/CMakeLists.txt +++ b/test/bacnet/basic/object/csv/CMakeLists.txt @@ -52,6 +52,7 @@ add_executable(${PROJECT_NAME} ${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 diff --git a/test/bacnet/basic/object/csv/src/main.c b/test/bacnet/basic/object/csv/src/main.c index a2947659..96d150ae 100644 --- a/test/bacnet/basic/object/csv/src/main.c +++ b/test/bacnet/basic/object/csv/src/main.c @@ -98,7 +98,7 @@ static void testCharacterString_Value(void) void test_main(void) { - ztest_test_suite(piv_tests, ztest_unit_test(testCharacterString_Value)); + ztest_test_suite(csv_tests, ztest_unit_test(testCharacterString_Value)); - ztest_run_test_suite(piv_tests); + ztest_run_test_suite(csv_tests); }