Files
bacnet_stack/zephyr/subsys/bacnet_settings/bacnet_settings.c
T
Kari Argillander 369da70f2a Strip tabs and trailing white spaces, and fix end of files (#748)
* format: Strip trailing whitespaces

We want to get rid of trailing whitespaces completly as they make just git
noice. Much better to start using automated tools to get rid of them once and
not getting them back again. This way git history will be cleaner and review
easier.

Commit was generated with:

    pre-commit run --all-files trailing-whitespace

* format: Files should have exactly one new line end of them

It is good practice that every file has one new line. It is not now days so
mandatory but it also is not nice if file has lot of newlines end of it. We will
use pre-commit which takes automatically care about this so let's fix all.

Commit was generated with:

    pre-commit run --all-files end-of-file-fixer

* format: Convert tabs to spaces

Project mostly use spaces over tabs. When mixing tabs and spaces this usually
makes formatting issues and also when changing those in commits it will make lot
of git noise. We will force spaces most of the time and use pre-commit to fix.

Commit was generated with:

    pre-commit run --all-files remove-tabs

---------

Co-authored-by: Kari Argillander <kari.argillander@fidelix.com>
2024-08-25 14:13:57 -05:00

380 lines
13 KiB
C

/**
* @file
* @brief Handle Get/Set of BACnet application encoded settings
* @date May 2024
* @author Steve Karg <skarg@users.sourceforge.net>
* @copyright SPDX-License-Identifier: MIT
*/
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <zephyr/sys/byteorder.h>
#include <bacnet_settings/bacnet_storage.h>
#include <bacnet_settings/bacnet_settings.h>
#include "bacnet/bacdef.h"
#include "bacnet/bacapp.h"
#include "bacnet/bacdcode.h"
#include "bacnet/bacstr.h"
#include "bacnet/bacint.h"
/**
* @brief Get a BACnet SIGNED INTEGER value from non-volatile storage
* @param object_type [in] The BACnet object type
* @param object_instance [in] The BACnet object instance
* @param property_id [in] The BACnet property id
* @param array_index [in] The BACnet array index
* @param default_value [in] The default value if not found
* @return stored data length on success 0..N, negative on failure.
*/
int bacnet_settings_value_get(uint16_t object_type, uint32_t object_instance,
uint32_t property_id, uint32_t array_index,
BACNET_APPLICATION_DATA_VALUE *value)
{
uint8_t name[BACNET_STORAGE_VALUE_SIZE_MAX + 1] = { 0 };
BACNET_STORAGE_KEY key = { 0 };
int stored_len, len;
bacnet_storage_key_init(&key, object_type, object_instance, property_id,
array_index);
stored_len = bacnet_storage_get(&key, name, sizeof(name));
if (stored_len > 0) {
len = bacapp_decode_application_data(name, stored_len, value);
if (len <= 0) {
if (value) {
value->tag = MAX_BACNET_APPLICATION_TAG;
}
}
}
return stored_len;
}
/**
* @brief Store a BACnet SIGNED INTEGER value in non-volatile storage
* @param object_type [in] The BACnet object type
* @param object_instance [in] The BACnet object instance
* @param property_id [in] The BACnet property id
* @param array_index [in] The BACnet array index
* @param value [in] The value to store
* @return true on success, false on failure.
*/
bool bacnet_settings_value_set(uint16_t object_type, uint32_t object_instance,
uint32_t property_id, uint32_t array_index,
BACNET_APPLICATION_DATA_VALUE *value)
{
uint8_t name[BACNET_STORAGE_VALUE_SIZE_MAX] = { 0 };
BACNET_STORAGE_KEY key = { 0 };
int rc, len;
bacnet_storage_key_init(&key, object_type, object_instance, property_id,
array_index);
len = bacapp_encode_application_data(NULL, value);
if (len <= 0) {
return false;
} else if (len > sizeof(name)) {
return false;
}
len = bacapp_encode_application_data(name, value);
rc = bacnet_storage_set(&key, name, len);
return rc == 0;
}
/**
* @brief Get a BACnet REAL value from non-volatile storage
* @param object_type [in] The BACnet object type
* @param object_instance [in] The BACnet object instance
* @param property_id [in] The BACnet property id
* @param array_index [in] The BACnet array index
* @param default_value [in] The default value if not found
* @return stored data length on success 0..N, negative on failure.
*/
int bacnet_settings_real_get(uint16_t object_type, uint32_t object_instance,
uint32_t property_id, uint32_t array_index,
float default_value, float *value)
{
int stored_len;
BACNET_APPLICATION_DATA_VALUE bvalue = { 0 };
stored_len =
bacnet_settings_value_get(object_type, object_instance,
property_id, array_index, &bvalue);
if ((stored_len >= 0) && (bvalue.tag == BACNET_APPLICATION_TAG_REAL)) {
if (value) {
*value = bvalue.type.Real;
}
} else {
if (value) {
*value = default_value;
}
}
return stored_len;
}
/**
* @brief Store a BACnet REAL value in non-volatile storage
* @param object_type [in] The BACnet object type
* @param object_instance [in] The BACnet object instance
* @param property_id [in] The BACnet property id
* @param array_index [in] The BACnet array index
* @param value [in] The value to store
* @return true on success, false on failure.
*/
bool bacnet_settings_real_set(uint16_t object_type, uint32_t object_instance,
uint32_t property_id, uint32_t array_index,
float value)
{
BACNET_APPLICATION_DATA_VALUE bvalue = { 0 };
bvalue.context_specific = false;
bvalue.tag = BACNET_APPLICATION_TAG_REAL;
bvalue.type.Real = value;
return bacnet_settings_value_set(object_type, object_instance,
property_id, array_index, &bvalue);
}
/**
* @brief Get a BACnet UNSIGNED value from non-volatile storage
* @param object_type [in] The BACnet object type
* @param object_instance [in] The BACnet object instance
* @param property_id [in] The BACnet property id
* @param default_value [in] The default value if not found
* @return stored data length on success 0..N, negative on failure.
*/
int bacnet_settings_unsigned_get(uint16_t object_type, uint32_t object_instance,
uint32_t property_id, uint32_t array_index,
BACNET_UNSIGNED_INTEGER default_value,
BACNET_UNSIGNED_INTEGER *value)
{
uint8_t name[BACNET_STORAGE_VALUE_SIZE_MAX + 1] = { 0 };
BACNET_STORAGE_KEY key = { 0 };
int stored_len, len;
bacnet_storage_key_init(&key, object_type, object_instance, property_id,
array_index);
stored_len = bacnet_storage_get(&key, name, sizeof(name));
if (stored_len > 0) {
len = bacnet_unsigned_application_decode(name, stored_len,
value);
if (len <= 0) {
if (value) {
*value = default_value;
}
}
} else {
if (value) {
*value = default_value;
}
}
return stored_len;
}
/**
* @brief Store a BACnet UNSIGNED value in non-volatile storage
* @param object_type [in] The BACnet object type
* @param object_instance [in] The BACnet object instance
* @param property_id [in] The BACnet property id
* @param value [int] The value to store
* @return true on success, false on failure.
*/
bool bacnet_settings_unsigned_set(uint16_t object_type,
uint32_t object_instance,
uint32_t property_id, uint32_t array_index,
BACNET_UNSIGNED_INTEGER value)
{
BACNET_APPLICATION_DATA_VALUE bvalue = { 0 };
bvalue.context_specific = false;
bvalue.tag = BACNET_APPLICATION_TAG_UNSIGNED_INT;
bvalue.type.Unsigned_Int = value;
return bacnet_settings_value_set(object_type, object_instance,
property_id, array_index, &bvalue);
}
/**
* @brief Get a BACnet SIGNED INTEGER value from non-volatile storage
* @param object_type [in] The BACnet object type
* @param object_instance [in] The BACnet object instance
* @param property_id [in] The BACnet property id
* @param array_index [in] The BACnet array index
* @param default_value [in] The default value if not found
* @return stored data length on success 0..N, negative on failure.
*/
int bacnet_settings_signed_get(uint16_t object_type, uint32_t object_instance,
uint32_t property_id, uint32_t array_index,
int32_t default_value, int32_t *value)
{
uint8_t name[BACNET_STORAGE_VALUE_SIZE_MAX + 1] = { 0 };
BACNET_STORAGE_KEY key = { 0 };
int stored_len, len;
bacnet_storage_key_init(&key, object_type, object_instance, property_id,
array_index);
stored_len = bacnet_storage_get(&key, name, sizeof(name));
if (stored_len > 0) {
len = bacnet_signed_application_decode(name, stored_len, value);
if (len <= 0) {
if (value) {
*value = default_value;
}
}
} else {
if (value) {
*value = default_value;
}
}
return stored_len;
}
/**
* @brief Store a BACnet SIGNED INTEGER value in non-volatile storage
* @param object_type [in] The BACnet object type
* @param object_instance [in] The BACnet object instance
* @param property_id [in] The BACnet property id
* @param array_index [in] The BACnet array index
* @param value [in] The value to store
* @return true on success, false on failure.
*/
bool bacnet_settings_signed_set(uint16_t object_type, uint32_t object_instance,
uint32_t property_id, uint32_t array_index,
int32_t value)
{
BACNET_APPLICATION_DATA_VALUE bvalue = { 0 };
bvalue.context_specific = false;
bvalue.tag = BACNET_APPLICATION_TAG_SIGNED_INT;
bvalue.type.Signed_Int = value;
return bacnet_settings_value_set(object_type, object_instance,
property_id, array_index, &bvalue);
}
/**
* @brief Get a BACnet CHARACTER_STRING value from non-volatile storage
* @param object_type [in] The BACnet object type
* @param object_instance [in] The BACnet object instance
* @param property_id [in] The BACnet property id
* @param default_value [in] The default value if not found
* @param value [out] The character string value
* @return stored data length on success 0..N, negative on failure.
*/
int bacnet_settings_characterstring_get(uint16_t object_type,
uint32_t object_instance,
uint32_t property_id,
uint32_t array_index,
const char *default_value,
BACNET_CHARACTER_STRING *value)
{
uint8_t name[BACNET_STORAGE_VALUE_SIZE_MAX + 1] = { 0 };
BACNET_STORAGE_KEY key = { 0 };
int stored_len, len;
bacnet_storage_key_init(&key, object_type, object_instance, property_id,
array_index);
stored_len = bacnet_storage_get(&key, name, sizeof(name));
if (stored_len > 0) {
len = bacnet_character_string_application_decode(
name, stored_len, value);
if (len <= 0) {
characterstring_init_ansi(value, default_value);
}
} else {
characterstring_init_ansi(value, default_value);
}
return stored_len;
}
/**
* @brief Store a BACnet CHARACTER_STRING value to non-volatile storage
* @param object_type [in] The BACnet object type
* @param object_instance [in] The BACnet object instance
* @param property_id [in] The BACnet property id
* @param default_value [in] The default value if not found
* @param value [out] The character string value
* @return true on success, false on failure.
*/
bool bacnet_settings_characterstring_ansi_set(uint16_t object_type,
uint32_t object_instance,
uint32_t property_id,
uint32_t array_index,
const char *cstring)
{
BACNET_APPLICATION_DATA_VALUE bvalue = { 0 };
bool status;
bvalue.context_specific = false;
bvalue.tag = BACNET_APPLICATION_TAG_CHARACTER_STRING;
status = characterstring_init_ansi(&bvalue.type.Character_String,
cstring);
if (!status) {
status = bacnet_settings_value_set(object_type, object_instance,
property_id, array_index,
&bvalue);
}
return status;
}
/**
* @brief Get a C-string value from non-volatile storage
* @param object_type [in] The BACnet object type
* @param object_instance [in] The BACnet object instance
* @param property_id [in] The BACnet property id
* @param default_value [in] The default value if not found
* @param value [out] The string value
* @param value_size [in] The size of the string value
* @return stored data length on success 0..N, negative on failure.
*/
int bacnet_settings_string_get(uint16_t object_type, uint32_t object_instance,
uint32_t property_id, uint32_t array_index,
const char *default_value, char *value,
size_t value_size)
{
BACNET_STORAGE_KEY key = { 0 };
int rc;
bacnet_storage_key_init(&key, object_type, object_instance, property_id,
array_index);
rc = bacnet_storage_get(&key, value, value_size);
if (rc <= 0) {
if (default_value) {
strncpy(value, default_value, value_size);
rc = strlen(default_value);
}
}
return rc;
}
/**
* @brief Get a C-string value from non-volatile storage
* @param object_type [in] The BACnet object type
* @param object_instance [in] The BACnet object instance
* @param property_id [in] The BACnet property id
* @param default_value [in] The default value if not found
* @param value [in] The character string value
* @return true on success, false on failure.
*/
bool bacnet_settings_string_set(uint16_t object_type, uint32_t object_instance,
uint32_t property_id, uint32_t array_index,
const char *value)
{
BACNET_STORAGE_KEY key = { 0 };
int rc;
if (!value) {
return false;
}
bacnet_storage_key_init(&key, object_type, object_instance, property_id,
array_index);
rc = bacnet_storage_set(&key, (const char *)value, strlen(value) + 1);
return rc == 0;
}