From a0a1eaa6dc29082b9b5ab1594c3043e725949d70 Mon Sep 17 00:00:00 2001 From: eeff <33566201+eeff@users.noreply.github.com> Date: Wed, 8 Feb 2023 12:03:08 +0800 Subject: [PATCH] feat(core): pack static value pointer in tag meta data --- include/neuron/tag.h | 15 ++++-- src/adapter/driver/driver.c | 8 ++- src/base/group.c | 38 +++---------- src/base/tag.c | 103 +++++++++++++++++++++++++++++++++--- 4 files changed, 120 insertions(+), 44 deletions(-) diff --git a/include/neuron/tag.h b/include/neuron/tag.h index 271dd029..31c223a8 100644 --- a/include/neuron/tag.h +++ b/include/neuron/tag.h @@ -87,14 +87,18 @@ typedef struct { uint8_t meta[NEU_TAG_META_SIZE]; } neu_datatag_t; -inline static bool neu_tag_attribute_test(neu_datatag_t * tag, - neu_attribute_e attribute) +UT_icd *neu_tag_get_icd(); + +neu_datatag_t *neu_tag_dup(const neu_datatag_t *tag); +void neu_tag_copy(neu_datatag_t *tag, const neu_datatag_t *other); +void neu_tag_free(neu_datatag_t *tag); + +inline static bool neu_tag_attribute_test(const neu_datatag_t *tag, + neu_attribute_e attribute) { return (tag->attribute & attribute) == attribute; } -UT_icd *neu_tag_get_icd(); - /** * @brief Special usage of parsing tag address, e.g. setting length of string * type, setting of endian. @@ -117,4 +121,7 @@ int neu_datatag_string_dtoh(char *str, int len); int neu_datatag_string_tod(char *str, int len, int buf_len); int neu_datatag_string_toe(char *str, int len, int buf_len); +int neu_tag_get_static_value(const neu_datatag_t *tag, neu_value_u *value); +int neu_tag_set_static_value(neu_datatag_t *tag, neu_value_u *value); + #endif \ No newline at end of file diff --git a/src/adapter/driver/driver.c b/src/adapter/driver/driver.c index 23e44a52..a1a100d9 100644 --- a/src/adapter/driver/driver.c +++ b/src/adapter/driver/driver.c @@ -400,6 +400,7 @@ void neu_adapter_driver_write_tag(neu_adapter_driver_t *driver, if (neu_tag_attribute_test(tag, NEU_ATTRIBUTE_STATIC)) { neu_driver_cache_add(g->driver->cache, g->name, tag->name, cmd->value); + neu_tag_set_static_value(tag, &cmd->value.value); neu_resp_error_t error = { .error = NEU_ERR_SUCCESS }; req->type = NEU_RESP_ERROR; driver->adapter.cb_funs.response(&driver->adapter, req, &error); @@ -825,8 +826,11 @@ static void group_change(void *arg, int64_t timestamp, UT_array *static_tags, neu_dvalue_t value = { 0 }; value.precision = tag->precision; - value.type = NEU_TYPE_ERROR; - value.value.i32 = NEU_ERR_PLUGIN_TAG_NOT_READY; + value.type = tag->type; + if (0 != neu_tag_get_static_value(tag, &value.value)) { + value.type = NEU_TYPE_ERROR; + value.value.i32 = NEU_ERR_EINTERNAL; + } neu_driver_cache_add(group->driver->cache, group->name, tag->name, value); diff --git a/src/base/group.c b/src/base/group.c index 346c8b61..d525355c 100644 --- a/src/base/group.c +++ b/src/base/group.c @@ -65,10 +65,7 @@ void neu_group_destroy(neu_group_t *group) { HASH_DEL(group->tags, el); free(el->name); - free(el->tag->name); - free(el->tag->address); - free(el->tag->description); - free(el->tag); + neu_tag_free(el->tag); free(el); } @@ -118,18 +115,9 @@ int neu_group_add_tag(neu_group_t *group, neu_datatag_t *tag) return NEU_ERR_TAG_NAME_CONFLICT; } - el = calloc(1, sizeof(tag_elem_t)); - el->name = strdup(tag->name); - el->tag = calloc(1, sizeof(neu_datatag_t)); - el->tag->name = strdup(tag->name); - el->tag->address = strdup(tag->address); - el->tag->description = strdup(tag->description); - el->tag->type = tag->type; - el->tag->attribute = tag->attribute; - el->tag->precision = tag->precision; - el->tag->decimal = tag->decimal; - el->tag->option = tag->option; - memcpy(el->tag->meta, tag->meta, sizeof(tag->meta)); + el = calloc(1, sizeof(tag_elem_t)); + el->name = strdup(tag->name); + el->tag = neu_tag_dup(tag); HASH_ADD_STR(group->tags, name, el); update_timestamp(group); @@ -144,18 +132,7 @@ int neu_group_update_tag(neu_group_t *group, neu_datatag_t *tag) HASH_FIND_STR(group->tags, tag->name, el); if (el != NULL) { - free(el->tag->address); - el->tag->address = strdup(tag->address); - - free(el->tag->description); - el->tag->description = strdup(tag->description); - - el->tag->type = tag->type; - el->tag->attribute = tag->attribute; - el->tag->precision = tag->precision; - el->tag->decimal = tag->decimal; - el->tag->option = tag->option; - memcpy(el->tag->meta, tag->meta, sizeof(tag->meta)); + neu_tag_copy(el->tag, tag); update_timestamp(group); ret = NEU_ERR_SUCCESS; @@ -173,10 +150,7 @@ int neu_group_del_tag(neu_group_t *group, const char *tag_name) if (el != NULL) { HASH_DEL(group->tags, el); free(el->name); - free(el->tag->name); - free(el->tag->address); - free(el->tag->description); - free(el->tag); + neu_tag_free(el->tag); free(el); update_timestamp(group); diff --git a/src/base/tag.c b/src/base/tag.c index 429a4dfb..8b65910f 100644 --- a/src/base/tag.c +++ b/src/base/tag.c @@ -24,20 +24,42 @@ config_ **/ #include "errcodes.h" #include "tag.h" +#define GET_STATIC_VALUE_PTR(tag, out) \ + do { \ + memcpy(&(out), (tag)->meta, sizeof(neu_value_u *)); \ + } while (0) + +#define SET_STATIC_VALUE_PTR(tag, ptr) \ + do { \ + memcpy((tag)->meta, &(ptr), sizeof(neu_value_u *)); \ + } while (0) + static void tag_array_copy(void *_dst, const void *_src) { neu_datatag_t *dst = (neu_datatag_t *) _dst; neu_datatag_t *src = (neu_datatag_t *) _src; - dst->type = src->type; - dst->attribute = src->attribute; - dst->precision = src->precision; - dst->decimal = src->decimal; - dst->option = src->option; - memcpy(dst->meta, src->meta, sizeof(src->meta)); + dst->type = src->type; + dst->attribute = src->attribute; + dst->precision = src->precision; + dst->decimal = src->decimal; + dst->option = src->option; dst->address = strdup(src->address); dst->name = strdup(src->name); dst->description = strdup(src->description); + + if (NEU_ATTRIBUTE_STATIC & src->attribute) { + neu_value_u *dst_val = NULL, *src_val = NULL; + GET_STATIC_VALUE_PTR(src, src_val); + if (src_val && (dst_val = calloc(1, sizeof(*dst_val)))) { + memcpy(dst_val, src_val, sizeof(*dst_val)); + SET_STATIC_VALUE_PTR(dst, dst_val); + } else { + memset(dst->meta, 0, sizeof(dst->meta)); + } + } else { + memcpy(dst->meta, src->meta, sizeof(src->meta)); + } } static void tag_array_free(void *_elt) @@ -47,6 +69,13 @@ static void tag_array_free(void *_elt) free(elt->name); free(elt->address); free(elt->description); + + if (NEU_ATTRIBUTE_STATIC & elt->attribute) { + neu_value_u *cur = NULL; + GET_STATIC_VALUE_PTR(elt, cur); + free(cur); + memset(elt->meta, 0, sizeof(elt->meta)); + } } static UT_icd tag_icd = { sizeof(neu_datatag_t), NULL, tag_array_copy, @@ -57,6 +86,29 @@ UT_icd *neu_tag_get_icd() return &tag_icd; } +neu_datatag_t *neu_tag_dup(const neu_datatag_t *tag) +{ + neu_datatag_t *new = calloc(1, sizeof(*new)); + tag_array_copy(new, tag); + return new; +} + +void neu_tag_copy(neu_datatag_t *tag, const neu_datatag_t *other) +{ + if (tag) { + tag_array_free(tag); + tag_array_copy(tag, other); + } +} + +void neu_tag_free(neu_datatag_t *tag) +{ + if (tag) { + tag_array_free(tag); + free(tag); + } +} + static char *find_last_character(char *str, char character) { char *find = strchr(str, character); @@ -346,3 +398,42 @@ int neu_datatag_string_toe(char *str, int len, int buf_len) free(t); return len * 2; } + +int neu_tag_get_static_value(const neu_datatag_t *tag, neu_value_u *value) +{ + neu_value_u *cur = NULL; + + if (!neu_tag_attribute_test(tag, NEU_ATTRIBUTE_STATIC)) { + return -1; + } + + GET_STATIC_VALUE_PTR(tag, cur); + if (NULL == cur) { + return -1; + } + + memcpy(value, cur, sizeof(*cur)); + return 0; +} + +int neu_tag_set_static_value(neu_datatag_t *tag, neu_value_u *value) +{ + neu_value_u *cur = NULL; + + if (!neu_tag_attribute_test(tag, NEU_ATTRIBUTE_STATIC)) { + return -1; + } + + GET_STATIC_VALUE_PTR(tag, cur); + if (NULL == cur) { + cur = calloc(1, sizeof(*cur)); + if (NULL == cur) { + return -1; + } + SET_STATIC_VALUE_PTR(tag, cur); + } + + memcpy(cur, value, sizeof(*cur)); + + return 0; +}