From cbe18b0d4e7192160cf7cc54cf4a6953bd8c70d6 Mon Sep 17 00:00:00 2001 From: ypc <15051963820@163.com> Date: Sat, 27 Jun 2026 15:15:50 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=8B=86=E5=88=86=20dc=5Fsignal.cp?= =?UTF-8?q?p=20=E6=8C=89=E5=8A=9F=E8=83=BD=E4=B8=BA10=E4=B8=AA=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - dc_signal.cpp (32行) → 全局变量 + XXH128Hash/Equal 实现 - dc_signal_query.cpp → cfg_change + 5个 get_*_info + out_change_check - dc_signal_compare.cpp → dc_data_compare + dc_signal_apply_metadata - dc_signal_ctrl.cpp → 4个 dc_check_* 控制校验函数 - dc_signal_core.cpp → add_to_map + 17个注册/设置函数 - dc_signal_find.cpp → 3个 dc_find_* 查找函数 - dc_signal_util.cpp → 类型映射表 + dc_get_signal_val 等工具 - dc_cfg_check.cpp → dc_param_cfg_check XML 写入 - dc_signal_show.cpp → 调试显示 + CLI 命令 - dc_signal_internal.h → 内部共享头文件 跨文件函数移除 LOCAL/static,全局变量 extern 声明集中管理。 对外 API 不变,所有调用方零改动。 --- src/public/libdatacenter/src/dc_cfg_check.cpp | 100 + src/public/libdatacenter/src/dc_signal.cpp | 2411 +---------------- .../libdatacenter/src/dc_signal_compare.cpp | 81 + .../libdatacenter/src/dc_signal_core.cpp | 765 ++++++ .../libdatacenter/src/dc_signal_ctrl.cpp | 423 +++ .../libdatacenter/src/dc_signal_find.cpp | 25 + .../libdatacenter/src/dc_signal_internal.h | 93 + .../libdatacenter/src/dc_signal_query.cpp | 206 ++ .../libdatacenter/src/dc_signal_show.cpp | 232 ++ .../libdatacenter/src/dc_signal_util.cpp | 484 ++++ 10 files changed, 2432 insertions(+), 2388 deletions(-) create mode 100644 src/public/libdatacenter/src/dc_cfg_check.cpp create mode 100644 src/public/libdatacenter/src/dc_signal_compare.cpp create mode 100644 src/public/libdatacenter/src/dc_signal_core.cpp create mode 100644 src/public/libdatacenter/src/dc_signal_ctrl.cpp create mode 100644 src/public/libdatacenter/src/dc_signal_find.cpp create mode 100644 src/public/libdatacenter/src/dc_signal_internal.h create mode 100644 src/public/libdatacenter/src/dc_signal_query.cpp create mode 100644 src/public/libdatacenter/src/dc_signal_show.cpp create mode 100644 src/public/libdatacenter/src/dc_signal_util.cpp diff --git a/src/public/libdatacenter/src/dc_cfg_check.cpp b/src/public/libdatacenter/src/dc_cfg_check.cpp new file mode 100644 index 0000000..ecd8ab0 --- /dev/null +++ b/src/public/libdatacenter/src/dc_cfg_check.cpp @@ -0,0 +1,100 @@ +#include "dc_signal_internal.h" +#include "tinyxml2.h" +void dc_param_cfg_check(const std::string &path) +{ + if (false == dc_get_param_cfg_change()) return; + + using namespace tinyxml2; + + XMLDocument doc; + doc.InsertEndChild(doc.NewDeclaration()); + + XMLElement *root = doc.NewElement("Root"); + doc.InsertEndChild(root); + + int ao_no = 0, param_no = 0; + + XMLElement *ao_elem = doc.NewElement("Ao"); + + // for(auto it = g_datacenter.signal_ao.map_signals.begin(); it != g_datacenter.signal_ao.map_signals.end(); it++) + for(uint32_t i = 0; i < g_datacenter.signal_ao.signal_id; i++) + { + stru_signal *p_ao = dc_find_signal_by_id(i, g_datacenter.signal_ao); + if(nullptr == p_ao) + { + MY_LOG_E("ao id %d not found", i); + continue; + } + + XMLElement *sig_elem = doc.NewElement("Signal"); + sig_elem->SetAttribute("id", p_ao->id); + sig_elem->SetAttribute("saddr", p_ao->saddr.c_str()); + sig_elem->SetAttribute("desc", p_ao->desc.c_str()); + sig_elem->SetAttribute("type", dc_get_data_type_str_by_id(p_ao->data_type).c_str()); + sig_elem->SetAttribute("min", p_ao->param.min); + sig_elem->SetAttribute("max", p_ao->param.max); + sig_elem->SetAttribute("step", p_ao->param.step); + sig_elem->SetAttribute("unit", p_ao->param.unit.c_str()); + sig_elem->SetAttribute("value", dc_get_signal_val(p_ao->vec_p_data[0], p_ao->data_type).c_str()); + + ao_elem->InsertEndChild(sig_elem); + } + + XMLElement *param_elem = doc.NewElement("Param"); + + // for(auto it = g_datacenter.signal_param.map_signals.begin(); it != g_datacenter.signal_param.map_signals.end(); it++) + for(uint32_t i = 0; i < g_datacenter.signal_param.signal_id; i++) + { + stru_signal *p_param = dc_find_signal_by_id(i, g_datacenter.signal_param); + if(nullptr == p_param) + { + MY_LOG_E("param id %d not found", i); + continue; + } + + XMLElement *sig_elem = doc.NewElement("Signal"); + sig_elem->SetAttribute("saddr", p_param->saddr.c_str()); + sig_elem->SetAttribute("desc", p_param->desc.c_str()); + sig_elem->SetAttribute("type", dc_get_data_type_str_by_id(p_param->data_type).c_str()); + sig_elem->SetAttribute("min", p_param->param.min); + sig_elem->SetAttribute("max", p_param->param.max); + sig_elem->SetAttribute("step", p_param->param.step); + sig_elem->SetAttribute("unit", p_param->param.unit.c_str()); + sig_elem->SetAttribute("num", p_param->vec_p_data.size()); + + + for(int i = 0; i < p_param->vec_p_data.size(); i++) + { + std::string val = dc_get_signal_val(p_param->vec_p_data[i], p_param->data_type); + + XMLElement *item_elem = doc.NewElement("Item"); + item_elem->SetAttribute("index", i+1); + item_elem->SetAttribute("value", val.c_str()); + + sig_elem->InsertEndChild(item_elem); + } + + param_elem->InsertEndChild(sig_elem); + } + + root->InsertEndChild(ao_elem); + root->InsertEndChild(param_elem); + + // 保存到 self_param.xml,不覆盖参数模板 param.xml + std::string self_path = path; + size_t pos = self_path.rfind("param.xml"); + if (pos != std::string::npos) + self_path.replace(pos, 9, "self_param.xml"); + + if (XML_SUCCESS == doc.SaveFile(self_path.c_str())) + { + dc_set_param_cfg_change(false); + MY_LOG_I("param runtime saved to %s", self_path.c_str()); + } + else + { + MY_LOG_E("failed to save param runtime to %s", self_path.c_str()); + } +} + + diff --git a/src/public/libdatacenter/src/dc_signal.cpp b/src/public/libdatacenter/src/dc_signal.cpp index 9879a44..4293152 100644 --- a/src/public/libdatacenter/src/dc_signal.cpp +++ b/src/public/libdatacenter/src/dc_signal.cpp @@ -1,2397 +1,32 @@ -#include -#include -#include -#include -#include -#include +#include "dc_signal_internal.h" -#include "dc_signal.h" -#include "dc_param.h" -#include "myLog.h" -#include "myCmd.h" +// XXH128Hash 实现 +size_t XXH128Hash::operator()(const XXH128_hash_t& h) const noexcept { + const uint64_t mix1 = h.low64 ^ (h.high64 << 17); + const uint64_t mix2 = mix1 + (h.high64 >> 13); + const uint64_t mix3 = mix2 ^ (h.low64 << 23); + return static_cast(mix3 ^ (mix3 >> 32)); +} -#include "tinyxml2.h" +// XXH128Equal 实现 +bool XXH128Equal::operator()(const XXH128_hash_t& a, const XXH128_hash_t& b) const noexcept { +#ifdef XXH128_isEqual + return XXH128_isEqual(a, b); +#else + return (a.high64 == b.high64) && (a.low64 == b.low64); +#endif +} -#include "myDatacenter.h" +// 全局变量 +stru_datacenter g_datacenter = {}; +bool g_param_cfg_change = false; +std::mutex g_param_cfg_change_mutex; +std::vector g_dirty_out_signals; +std::mutex g_dirty_out_mutex; -struct XXH128Hash { - size_t operator()(const XXH128_hash_t& h) const noexcept { - // 低版本库无XXH3_64bits_fromCanonical,手动混合高低64位生成哈希 - // 采用经典的混合算法,减少哈希冲突概率 - const uint64_t mix1 = h.low64 ^ (h.high64 << 17); - const uint64_t mix2 = mix1 + (h.high64 >> 13); - const uint64_t mix3 = mix2 ^ (h.low64 << 23); - // 转size_t(兼容32/64位系统) - return static_cast(mix3 ^ (mix3 >> 32)); - } -}; - -struct XXH128Equal { - bool operator()(const XXH128_hash_t& a, const XXH128_hash_t& b) const noexcept { - // 优先用库自带的相等判断(v0.8.0+有),没有则手动比较 - #ifdef XXH128_isEqual - return XXH128_isEqual(a, b); - #else - return (a.high64 == b.high64) && (a.low64 == b.low64); - #endif - } -}; - -typedef std::unordered_multimap hash_signal_map; - - -typedef struct -{ - std::mutex mtx; - uint32_t signal_id; - hash_signal_map map_signals; - std::vector id_index; // ID→指针 O(1) 索引 -}stru_signal_map; - - -typedef struct -{ - stru_signal_map signal_out; - stru_signal_map signal_in; - stru_signal_map signal_yk; - stru_signal_map signal_ao; - stru_signal_map signal_param; -}stru_datacenter; - - -static stru_datacenter g_datacenter = {}; - -LOCAL bool g_param_cfg_change = false; -LOCAL std::mutex g_param_cfg_change_mutex; - -// 脏信号队列:记录值发生变化的 out 信号,用于增量变化检测 -static std::vector g_dirty_out_signals; -static std::mutex g_dirty_out_mutex; - -static void dc_mark_signal_dirty(stru_signal *p_signal) +void dc_mark_signal_dirty(stru_signal *p_signal) { if (p_signal == nullptr) return; std::lock_guard lock(g_dirty_out_mutex); g_dirty_out_signals.push_back(p_signal); } - - - -LOCAL int dc_data_compare(uint8_t data_type, void *p_data, void *p_data2); -LOCAL int dc_set_signal_val(void *p_data, uint8_t data_type, void *set_data); -LOCAL stru_signal* dc_find_signal(const std::string &saddr, stru_signal_map &dc_signal_map); -LOCAL int dc_signal_add_to_map(stru_signal &signal, stru_signal_map &dc_signal_map); -LOCAL stru_signal* dc_find_out_signal(const std::string &saddr); -LOCAL stru_signal* dc_find_in_signal(const std::string &saddr); - - -bool dc_get_param_cfg_change() -{ - bool change = false; - std::lock_guard lock(g_param_cfg_change_mutex); - change = g_param_cfg_change; - - return change; -} - -void dc_set_param_cfg_change(bool change) -{ - std::lock_guard lock(g_param_cfg_change_mutex); - g_param_cfg_change = change; -} - - - - -int dc_get_out_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, void **p_data) -{ - stru_signal *p_signal = dc_find_out_signal(saddr); - if(p_signal == nullptr) - { - MY_LOG_E("saddr %s not found", saddr.c_str()); - return -1; - } - - desc = p_signal->desc; - data_type = p_signal->data_type; - - if(p_signal->vec_p_data.empty()) - { - MY_LOG_E("saddr %s vec_p_data is empty", saddr.c_str()); - return -1; - } - - if(nullptr == p_signal->vec_p_data[0]) - { - MY_LOG_E("saddr %s vec_p_data[0] is nullptr", saddr.c_str()); - return -1; - } - - if(p_data != nullptr) - { - (*p_data) = p_signal->vec_p_data[0]; - } - - return 0; -} - -int dc_get_in_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, void **p_data) -{ - stru_signal *p_signal = dc_find_in_signal(saddr); - if(p_signal == nullptr) - { - MY_LOG_E("saddr %s not found", saddr.c_str()); - return -1; - } - - desc = p_signal->desc; - data_type = p_signal->data_type; - - if(!p_signal->vec_p_data.empty() && nullptr != p_signal->vec_p_data[0]) - { - if(p_data != nullptr) - { - (*p_data) = p_signal->vec_p_data[0]; - } - - return 0; - } - - MY_LOG_E("saddr %s vec_p_data is empty or vec_p_data[0] is nullptr", saddr.c_str()); - return -1; -} - -int dc_get_ao_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param *p_param, uint8_t &ctrl_type, void **p_data) -{ - stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao); - if(p_signal == nullptr) - { - MY_LOG_E("saddr %s not found", saddr.c_str()); - return -1; - } - - desc = p_signal->desc; - data_type = p_signal->data_type; - if(p_param != nullptr) - { - p_param->min = p_signal->param.min; - p_param->max = p_signal->param.max; - p_param->step = p_signal->param.step; - p_param->unit = p_signal->param.unit; - } - ctrl_type = p_signal->ctrl_type; - - if(!p_signal->vec_p_data.empty() && nullptr != p_signal->vec_p_data[0]) - { - if(p_data != nullptr) - { - (*p_data) = p_signal->vec_p_data[0]; - } - } - else - { - MY_LOG_E("saddr %s vec_p_data is empty or vec_p_data[0] is nullptr", saddr.c_str()); - return -1; - } - - - return 0; -} - -int dc_get_param_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param *p_param, uint8_t &ctrl_type, std::vector *p_vec_p_data) -{ - stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param); - if(p_signal == nullptr) - { - MY_LOG_E("saddr %s not found", saddr.c_str()); - return -1; - } - desc = p_signal->desc; - data_type = p_signal->data_type; - if(p_param != nullptr) - { - p_param->min = p_signal->param.min; - p_param->max = p_signal->param.max; - p_param->step = p_signal->param.step; - p_param->unit = p_signal->param.unit; - } - ctrl_type = p_signal->ctrl_type; - - for(size_t i = 0; i < p_signal->vec_p_data.size(); i++) - { - if(nullptr == p_signal->vec_p_data[i]) - { - MY_LOG_E("saddr %s vec_p_data[%ld] is nullptr", saddr.c_str(), i); - return -1; - } - if(p_vec_p_data != nullptr) - { - p_vec_p_data->push_back(p_signal->vec_p_data[i]); - } - } - - - - return 0; -} - -int dc_get_yk_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, uint8_t &ctrl_type, void **p_data) -{ - stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_yk); - if(p_signal == nullptr) - { - MY_LOG_E("saddr %s not found", saddr.c_str()); - return -1; - } - desc = p_signal->desc; - data_type = p_signal->data_type; - ctrl_type = p_signal->ctrl_type; - if(p_data != nullptr) - { - *p_data = p_signal->vec_p_data[0]; - } - - return 0; -} - - -void dc_signal_out_change_check() -{ - std::vector dirty; - { - std::lock_guard lock(g_dirty_out_mutex); - dirty.swap(g_dirty_out_signals); - } - - if (dirty.empty()) return; - - // 去重:同一信号可能多次写入 - std::sort(dirty.begin(), dirty.end()); - auto last = std::unique(dirty.begin(), dirty.end()); - - for (auto it = dirty.begin(); it != last; ++it) { - stru_signal *p_signal = *it; - if (!p_signal->out_change_cb_list.empty() && - nullptr != p_signal->vec_p_data[0] && - nullptr != p_signal->p_last_data) - { - if (0 != dc_data_compare(p_signal->data_type, - p_signal->vec_p_data[0], p_signal->p_last_data)) - { - for (auto &entry : p_signal->out_change_cb_list) { - // 回路阻断:修改本信号的模块不回调自身 - if (entry.first == p_signal->last_caller_module) continue; - entry.second(p_signal->saddr, p_signal->data_type, - p_signal->vec_p_data[0], p_signal->p_last_data); - } - dc_set_signal_val(p_signal->p_last_data, - p_signal->data_type, p_signal->vec_p_data[0]); - } - } - } -} - -LOCAL int dc_data_compare(uint8_t data_type, void *p_data, void *p_data2) -{ - if(p_data == nullptr || p_data2 == nullptr) - { - LOG_E("p_data or p_data2 is nullptr"); - return -1; - } - - float f1 = 0.0f; - float f2 = 0.0f; - double d1 = 0.0; - double d2 = 0.0; - - switch(data_type) - { - case DATA_TYPE_B: - case DATA_TYPE_U8: - return (*(uint8_t *)p_data == *(uint8_t *)p_data2) ? 0 : -1; - case DATA_TYPE_S8: - return (*(int8_t *)p_data == *(int8_t *)p_data2) ? 0 : -1; - case DATA_TYPE_S16: - return (*(int16_t *)p_data == *(int16_t *)p_data2) ? 0 : -1; - case DATA_TYPE_U16: - return (*(uint16_t *)p_data == *(uint16_t *)p_data2) ? 0 : -1; - case DATA_TYPE_S32: - return (*(int32_t *)p_data == *(int32_t *)p_data2) ? 0 : -1; - case DATA_TYPE_U32: - return (*(uint32_t *)p_data == *(uint32_t *)p_data2) ? 0 : -1; - case DATA_TYPE_L64: - return (*(int64_t *)p_data == *(int64_t *)p_data2) ? 0 : -1; - case DATA_TYPE_UL64: - return (*(uint64_t *)p_data == *(uint64_t *)p_data2) ? 0 : -1; - case DATA_TYPE_F32: - f1 = *(float *)p_data; - f2 = *(float *)p_data2; - return f1 == f2 ? 0 : -1; - case DATA_TYPE_D64: - d1 = *(double *)p_data; - d2 = *(double *)p_data2; - return d1 == d2 ? 0 : -1; - case DATA_TYPE_C1: - return (*(char *)p_data == *(char *)p_data2) ? 0 : -1; - case DATA_TYPE_IP: - case DATA_TYPE_MAC: - case DATA_TYPE_C8: - case DATA_TYPE_C32: - case DATA_TYPE_C64: - case DATA_TYPE_C128: - case DATA_TYPE_STR: - return (0 == strcmp((char *)p_data, (char *)p_data2)) ? 0 : -1; - default: - LOG_E("unsupported data type %d", data_type); - return -1; - } - - return -1; -} - - -// 从中央元数据表查找并设置 signal.param -LOCAL void dc_signal_apply_metadata(stru_signal &signal) -{ - stru_signal_param param; - if (dc_param_metadata_lookup(signal.saddr, param)) - { - signal.param = param; - } - else - { - signal.param.min = 0.0f; - signal.param.max = 0.0f; - signal.param.step = 0.0f; - signal.param.unit.clear(); - } -} - - - - - - -LOCAL int dc_check_ctrl_val_valid(const stru_signal_ctrl &ctrl, const void *p_data) -{ - if(ctrl.data_type == DATA_TYPE_B || ctrl.data_type == DATA_TYPE_U8) - { - if(*(uint8_t *)p_data != *(uint8_t *)ctrl.p_data) - { - LOG_E("direct ctrl value %d not match selected value %d", *(uint8_t*)p_data, *(uint8_t*)ctrl.p_data); - return -1; - } - } - else if(ctrl.data_type == DATA_TYPE_S8) - { - if(*(int8_t *)p_data != *(int8_t *)ctrl.p_data) - { - LOG_E("direct ctrl value %d not match selected value %d", *(int8_t*)p_data, *(int8_t*)ctrl.p_data); - return -1; - } - } - else if(ctrl.data_type == DATA_TYPE_S16) - { - if(*(int16_t *)p_data != *(int16_t *)ctrl.p_data) - { - LOG_E("direct ctrl value %d not match selected value %d", *(int16_t*)p_data, *(int16_t*)ctrl.p_data); - return -1; - } - } - else if(ctrl.data_type == DATA_TYPE_U16) - { - if(*(uint16_t *)p_data != *(uint16_t *)ctrl.p_data) - { - LOG_E("direct ctrl value %d not match selected value %d", *(uint16_t*)p_data, *(uint16_t*)ctrl.p_data); - return -1; - } - } - else if(ctrl.data_type == DATA_TYPE_S32) - { - if(*(int32_t *)p_data != *(int32_t *)ctrl.p_data) - { - LOG_E("direct ctrl value %d not match selected value %d", *(int32_t*)p_data, *(int32_t*)ctrl.p_data); - return -1; - } - } - else if(ctrl.data_type == DATA_TYPE_U32) - { - if(*(uint32_t *)p_data != *(uint32_t *)ctrl.p_data) - { - LOG_E("direct ctrl value %d not match selected value %d", *(uint32_t*)p_data, *(uint32_t*)ctrl.p_data); - return -1; - } - } - else if(ctrl.data_type == DATA_TYPE_L64) - { - if(*(int64_t *)p_data != *(int64_t *)ctrl.p_data) - { - LOG_E("direct ctrl value %lld not match selected value %lld", *(int64_t*)p_data, *(int64_t*)ctrl.p_data); - return -1; - } - } - else if(ctrl.data_type == DATA_TYPE_UL64) - { - if(*(uint64_t *)p_data != *(uint64_t *)ctrl.p_data) - { - LOG_E("direct ctrl value %lld not match selected value %lld", *(uint64_t*)p_data, *(uint64_t*)ctrl.p_data); - return -1; - } - } - else if(ctrl.data_type == DATA_TYPE_F32) - { - if(*(float*)p_data != *(float*)ctrl.p_data) - { - LOG_E("direct ctrl value %f not match selected value %f", *(float*)p_data, *(float*)ctrl.p_data); - return -1; - } - } - else if(ctrl.data_type == DATA_TYPE_D64) - { - if(*(double*)p_data != *(double*)ctrl.p_data) - { - LOG_E("direct ctrl value %lf not match selected value %lf", *(double*)p_data, *(double*)ctrl.p_data); - return -1; - } - } - else if(ctrl.data_type == DATA_TYPE_IP) - { - if(0 != memcmp((char *)ctrl.p_data, (char *)p_data, 4)) - { - LOG_E("direct ctrl value %s not match selected value %s", - dc_get_signal_val(ctrl.p_data, DATA_TYPE_IP).c_str(), dc_get_signal_val((char *)p_data, DATA_TYPE_IP).c_str()); - return -1; - } - } - else if(ctrl.data_type == DATA_TYPE_MAC) - { - if(0 != memcmp((char *)ctrl.p_data, (char *)p_data, 6)) - { - LOG_E("direct ctrl value %s not match selected value %s", - dc_get_signal_val(ctrl.p_data, DATA_TYPE_MAC).c_str(), dc_get_signal_val((char *)p_data, DATA_TYPE_MAC).c_str()); - return -1; - } - } - else if(ctrl.data_type == DATA_TYPE_C1) - { - if(*(char*)p_data != *(char*)ctrl.p_data) - { - LOG_E("direct ctrl value %c not match selected value %c", *(char*)p_data, *(char*)ctrl.p_data); - return -1; - } - } - else if(ctrl.data_type == DATA_TYPE_C8 || ctrl.data_type == DATA_TYPE_C32 || ctrl.data_type == DATA_TYPE_C64 || ctrl.data_type == DATA_TYPE_C128 || ctrl.data_type == DATA_TYPE_STR) - { - if(0 != strcmp((char *)ctrl.p_data, (char *)p_data)) - { - LOG_E("direct ctrl value %s not match selected value %s", (char *)ctrl.p_data, (char *)p_data); - return -1; - } - } - else - { - LOG_E("invalid ctrl data_type %d", ctrl.data_type); - return -1; - } - - return 0; -} - -LOCAL int dc_check_ctrl_valid(const stru_signal *p_signal, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, const void *p_data) -{ - // LOG_I("dc_check_ctrl_valid %s, step %d, data_type %d, p_data %d", p_signal->saddr.c_str(), step, data_type, *(uint8_t *)p_data); - - if(p_signal->data_type != ctrl.data_type) - { - LOG_E("%s data_type %d not match ctrl data_type %d", p_signal->saddr.c_str(), p_signal->data_type, ctrl.data_type); - return -1; - } - - if(ctrl.type == SIGNAL_CTRL_TYPE::DIRECT_NORMAL) - { - if(step == SIGNAL_CTRL_STEP::DIRECT) - { - return 0; - } - else - { - LOG_E("%s ctrl_type %d, invalid ctrl step %d", p_signal->saddr.c_str(), ctrl.type, ctrl.step); - return -1; - } - } - else if(ctrl.type == SIGNAL_CTRL_TYPE::SBO_NORMAL) - { - if(ctrl.step == SIGNAL_CTRL_STEP::READY) - { - if(step == SIGNAL_CTRL_STEP::SELECT) - { - return 0; - } - else - { - LOG_E("%s ctrl_type %d, invalid ctrl step %d", p_signal->saddr.c_str(), ctrl.type, ctrl.step); - return -1; - } - } - else if(ctrl.step == SIGNAL_CTRL_STEP::SELECT) - { - if(step == SIGNAL_CTRL_STEP::DIRECT) - { - if(0 == dc_check_ctrl_val_valid(ctrl, p_data)) - { - return 0; - } - else - { - LOG_E("%s ctrl_type %d, direct value not match selected value", p_signal->saddr.c_str(), ctrl.type); - return -1; - } - } - else if(step == SIGNAL_CTRL_STEP::CANCEL) - { - return 0; - } - else - { - LOG_E("%s ctrl_type %d, invalid ctrl step %d", p_signal->saddr.c_str(), ctrl.type, ctrl.step); - return -1; - } - } - } - - LOG_E("invalid ctrl type %d", ctrl.type); - return -1; -} - - - -LOCAL int dc_check_val_valid(const stru_signal *p_signal, uint8_t setting_zone, const void *p_data) -{ - stru_signal_param param = p_signal->param; - - if(setting_zone >= p_signal->vec_p_data.size()) - { - LOG_E("%s setting_zone %d out of range, vec_p_data size %d", p_signal->saddr.c_str(), setting_zone, (int)p_signal->vec_p_data.size()); - return -1; - } - - void *current_p_data = p_signal->vec_p_data[setting_zone]; - - if(p_signal->data_type == DATA_TYPE_B) - { - if(*(uint8_t *)current_p_data == *(uint8_t *)p_data) - { - LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint8_t*)current_p_data); - return -1; - } - - uint8_t b = *(uint8_t*)p_data; - if(b != 0 && b != 1) - { - LOG_E("invalid bool value %d", b); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_S8) - { - if(*(int8_t*)current_p_data == *(int8_t*)p_data) - { - LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(int8_t*)current_p_data); - return -1; - } - - int8_t s8 = *(int8_t*)p_data; - if(s8 < (int8_t)param.min || s8 > (int8_t)param.max) - { - LOG_E("invalid int8_t value %d, range [%f, %f]", s8, param.min, param.max); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_U8) - { - if(*(uint8_t*)current_p_data == *(uint8_t*)p_data) - { - LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint8_t*)current_p_data); - return -1; - } - - uint8_t u8 = *(uint8_t*)p_data; - if(u8 < param.min || u8 > param.max) - { - LOG_E("invalid uint8_t value %d, range [%f, %f]", u8, param.min, param.max); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_S16) - { - if(*(int16_t*)current_p_data == *(int16_t*)p_data) - { - LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(int16_t*)current_p_data); - return -1; - } - - int16_t s16 = *(int16_t*)p_data; - if(s16 < (int16_t)param.min || s16 > (int16_t)param.max) - { - LOG_E("invalid int16_t value %d, range [%d, %d]", s16, param.min, param.max); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_U16) - { - if(*(uint16_t*)current_p_data == *(uint16_t*)p_data) - { - LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint16_t*)current_p_data); - return -1; - } - - uint16_t u16 = *(uint16_t*)p_data; - if(u16 < param.min || u16 > param.max) - { - LOG_E("invalid uint16_t value %d, range [%f, %f]", u16, param.min, param.max); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_S32) - { - if(*(int32_t*)current_p_data == *(int32_t*)p_data) - { - LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(int32_t*)current_p_data); - return -1; - } - - int32_t s32 = *(int32_t*)p_data; - if(s32 < (int32_t)param.min || s32 > (int32_t)param.max) - { - LOG_E("invalid int32_t value %d, range [%f, %f]", s32, param.min, param.max); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_U32) - { - if(*(uint32_t*)current_p_data == *(uint32_t*)p_data) - { - LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint32_t*)current_p_data); - return -1; - } - - uint32_t u32 = *(uint32_t*)p_data; - if(u32 < param.min || u32 > param.max) - { - LOG_E("invalid uint32_t value %d, range [%f, %f]", u32, param.min, param.max); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_L64) - { - if(*(int64_t*)current_p_data == *(int64_t*)p_data) - { - LOG_E("%s value %lld not changed", p_signal->saddr.c_str(), *(int64_t*)current_p_data); - return -1; - } - - int64_t l64 = *(int64_t*)p_data; - if(l64 < (int64_t)param.min || l64 > (int64_t)param.max) - { - LOG_E("invalid int64_t value %lld, range [%f, %f]", l64, param.min, param.max); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_UL64) - { - if(*(uint64_t*)current_p_data == *(uint64_t*)p_data) - { - LOG_E("%s value %llu not changed", p_signal->saddr.c_str(), *(uint64_t*)current_p_data); - return -1; - } - - uint64_t ul64 = *(uint64_t*)p_data; - if(ul64 < param.min || ul64 > param.max) - { - LOG_E("invalid uint64_t value %llu, range [%f, %f]", ul64, param.min, param.max); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_F32) - { - if(*(float*)current_p_data == *(float*)p_data) - { - LOG_E("%s value %f not changed", p_signal->saddr.c_str(), *(float*)current_p_data); - return -1; - } - - float f32 = *(float*)p_data; - if(f32 < (float)param.min || f32 > (float)param.max) - { - LOG_E("invalid float value %f, range [%f, %f]", f32, param.min, param.max); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_D64) - { - if(*(double*)current_p_data == *(double*)p_data) - { - LOG_E("%s value %f not changed", p_signal->saddr.c_str(), *(double*)current_p_data); - return -1; - } - - double d64 = *(double*)p_data; - if(d64 < (double)param.min || d64 > (double)param.max) - { - LOG_E("invalid double value %f, range [%f, %f]", d64, param.min, param.max); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_IP || - p_signal->data_type == DATA_TYPE_MAC || - p_signal->data_type == DATA_TYPE_C8 || - p_signal->data_type == DATA_TYPE_C32 || - p_signal->data_type == DATA_TYPE_C64 || - p_signal->data_type == DATA_TYPE_C128 || - p_signal->data_type == DATA_TYPE_STR) - { - if(0 == strcmp((char *)current_p_data, (char *)p_data)) - { - LOG_E("%s value %s not changed", p_signal->saddr.c_str(), (char*)current_p_data); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_C1) - { - if(*(char*)current_p_data == *(char*)p_data) - { - LOG_E("%s value %c not changed", p_signal->saddr.c_str(), *(char*)current_p_data); - return -1; - } - } - else - { - LOG_E("data_type is not valid: %d", p_signal->data_type); - return -1; - } - - return 0; -} - -LOCAL int dc_check_yk_val_valid(stru_signal *p_signal, void *p_data) -{ - if(p_signal->data_type == DATA_TYPE_B || p_signal->data_type == DATA_TYPE_U8) - { - uint8_t u8 = *(uint8_t*)p_data; - if(u8 != 0 && u8 != 1) - { - LOG_E("invalid uint8_t value %d, range [0, 1]", u8); - return -1; - } - } - else - { - LOG_E("data_type is not valid: %d", p_signal->data_type); - return -1; - } - - return 0; -} - - -LOCAL int dc_signal_add_to_map(stru_signal &signal, stru_signal_map &dc_signal_map) -{ - std::lock_guard lock(dc_signal_map.mtx); - - // 先查找是否已有相同 saddr 的信号(更新场景) - auto range = dc_signal_map.map_signals.equal_range(signal.hash); - for (auto it = range.first; it != range.second; ++it) { - if (it->second.saddr == signal.saddr) { - // 已有相同 saddr,更新内容,保留 id - uint32_t old_id = it->second.id; - it->second = signal; - it->second.id = old_id; - return 0; - } - } - - // 新信号,插入 multimap - auto it = dc_signal_map.map_signals.emplace(signal.hash, signal); - it->second.id = dc_signal_map.signal_id++; - if (dc_signal_map.id_index.size() <= it->second.id) { - dc_signal_map.id_index.resize(it->second.id + 1, nullptr); - } - dc_signal_map.id_index[it->second.id] = &it->second; - - return 0; -} - - -int dc_signal_out(const std::string &saddr, const std::string &desc, uint8_t data_type, void *p_data) -{ - if(p_data == nullptr) - { - MY_LOG_E("p_data is nullptr"); - return -1; - } - - stru_signal *p_signal = dc_find_out_signal(saddr); - if(nullptr != p_signal) - { - MY_LOG_E("saddr %s already registered", saddr.c_str()); - return -1; - } - - stru_signal signal; - - signal.hash = XXH3_128bits(saddr.c_str(), saddr.length()); - signal.saddr.assign(saddr); - signal.desc.assign(desc); - signal.data_type = data_type; - signal.vec_p_data.push_back(p_data); - void *p_last_data = dc_create_data_ptr_by_type(data_type); - if(p_last_data == nullptr) - { - MY_LOG_E("create p_last_data failed"); - return -1; - } - signal.p_last_data = p_last_data; - - // MY_LOG_I("saddr %s, p_data %p", saddr.c_str(), p_data); - return dc_signal_add_to_map(signal, g_datacenter.signal_out); -} - -int dc_signal_out_with_callback(const std::string &saddr, const std::string &desc, uint8_t data_type, void *p_data, out_signal_change_cb cb, const std::string &module_id) -{ - if(nullptr == p_data) - { - MY_LOG_E("p_data is nullptr"); - return -1; - } - - stru_signal *p_signal = dc_find_out_signal(saddr); - if(nullptr != p_signal) - { - MY_LOG_E("saddr %s already registered", saddr.c_str()); - return -1; - } - - stru_signal signal; - signal.hash = XXH3_128bits(saddr.c_str(), saddr.length()); - signal.saddr.assign(saddr); - signal.desc.assign(desc); - signal.data_type = data_type; - signal.vec_p_data.push_back(p_data); - void *p_last_data = dc_create_data_ptr_by_type(data_type); - if(p_last_data == nullptr) - { - MY_LOG_E("create p_last_data failed"); - return -1; - } - signal.p_last_data = p_last_data; - if(nullptr != cb) - { - signal.out_change_cb_list.push_back({module_id, cb}); - } - - return dc_signal_add_to_map(signal, g_datacenter.signal_out); -} - -int dc_signal_out_link_with_callback(const std::string &saddr, void **p_data, out_signal_change_cb cb, const std::string &module_id) -{ - stru_signal *p_signal = dc_find_out_signal(saddr); - if(nullptr == p_signal) - { - MY_LOG_E("saddr %s not found", saddr.c_str()); - return -1; - } - - if(p_signal->vec_p_data.empty() || nullptr == p_signal->vec_p_data[0]) - { - MY_LOG_E("saddr %s vec_p_data is empty or vec_p_data[0] is nullptr", saddr.c_str()); - return -1; - } - - if(p_data != nullptr) - { - (*p_data) = p_signal->vec_p_data[0]; - } - - if(nullptr != cb) - { - p_signal->out_change_cb_list.push_back({module_id, cb}); - } - - return 0; -} - -int dc_signal_in(const std::string &saddr, const std::string &desc, const std::string &link_saddr, void **p_data) -{ - if(p_data == nullptr) - { - MY_LOG_E("p_data is nullptr"); - return -1; - } - - stru_signal *p_signal = dc_find_in_signal(saddr); - if(nullptr != p_signal) - { - MY_LOG_E("saddr %s already registered", saddr.c_str()); - return -1; - } - - stru_signal signal; - - signal.hash = XXH3_128bits(saddr.c_str(), saddr.length()); - signal.saddr.assign(saddr); - signal.desc.assign(desc); - - if(link_saddr.empty()) - { - MY_LOG_E("link_saddr is empty"); - return -1; - } - - stru_signal *p_signal_out = dc_find_out_signal(link_saddr); - if(p_signal_out == nullptr) - { - MY_LOG_E("link_saddr %s not found", link_saddr.c_str()); - return -1; - } - - (*p_data) = p_signal_out->vec_p_data[0]; - signal.data_type = p_signal_out->data_type; - signal.vec_p_data.push_back((*p_data)); - - if(p_signal_out->link_set.find(saddr) == p_signal_out->link_set.end()) - { - p_signal_out->link_set.insert(saddr); - p_signal_out->link_saddrs.push_back(saddr); - } - - signal.link_saddrs.push_back(link_saddr); - - return dc_signal_add_to_map(signal, g_datacenter.signal_in); -} - -int dc_signal_in_with_callback(const std::string &saddr, const std::string &desc, const std::string &link_saddr, void **p_data, out_signal_change_cb cb, const std::string &module_id) -{ - if(p_data == nullptr) - { - MY_LOG_E("p_data is nullptr"); - return -1; - } - - stru_signal *p_signal = dc_find_in_signal(saddr); - if(nullptr != p_signal) - { - MY_LOG_E("saddr %s already registered", saddr.c_str()); - return -1; - } - - stru_signal signal; - signal.hash = XXH3_128bits(saddr.c_str(), saddr.length()); - signal.saddr.assign(saddr); - signal.desc.assign(desc); - - if(link_saddr.empty()) - { - MY_LOG_E("link_saddr is empty"); - return -1; - } - - stru_signal *p_signal_out = dc_find_out_signal(link_saddr); - if(p_signal_out == nullptr) - { - MY_LOG_E("link_saddr %s not found", link_saddr.c_str()); - return -1; - } - - (*p_data) = p_signal_out->vec_p_data[0]; - signal.data_type = p_signal_out->data_type; - signal.vec_p_data.push_back((*p_data)); - - if(nullptr != cb) - { - p_signal_out->out_change_cb_list.push_back({module_id, cb}); - } - - if(p_signal_out->link_set.find(saddr) == p_signal_out->link_set.end()) - { - p_signal_out->link_set.insert(saddr); - p_signal_out->link_saddrs.push_back(saddr); - } - - signal.link_saddrs.push_back(link_saddr); - - return dc_signal_add_to_map(signal, g_datacenter.signal_in); -} - -int dc_signal_ao(const std::string &saddr, const std::string &desc, uint8_t data_type, uint8_t ctrl_type, void *p_data, signal_change_cb cb, const std::string &module_id) -{ - if(p_data == nullptr) - { - MY_LOG_E("p_data is nullptr"); - return -1; - } - - XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao); - if(p_signal != nullptr && !p_signal->vec_p_data.empty() && nullptr != p_signal->vec_p_data[0]) - { - // Always copy old value to new pointer when data type matches - if(p_signal->data_type == data_type) - { - dc_set_signal_val(p_data, data_type, p_signal->vec_p_data[0]); - } - - { - std::lock_guard lock(g_datacenter.signal_ao.mtx); - dc_delete_signal_data(p_signal->vec_p_data[0], data_type); - p_signal->vec_p_data[0] = p_data; - p_signal->change_cb_list.push_back({module_id, cb}); - } - return 0; - } - - dc_set_param_cfg_change(true); - - stru_signal signal; - signal.hash = hash; - signal.saddr.assign(saddr); - signal.desc.assign(desc); - signal.data_type = data_type; - dc_signal_apply_metadata(signal); - signal.ctrl_type = ctrl_type; - - dc_signal_add_to_map(signal, g_datacenter.signal_ao); - - p_signal = dc_find_signal(saddr, g_datacenter.signal_ao); - if(p_signal != nullptr ) - { - p_signal->vec_p_data.push_back(p_data); - - if(cb) - { - p_signal->change_cb_list.push_back({module_id, cb}); - } - - return 0; - } - - return -1; -} - -int dc_signal_ao_link_with_callback(const std::string &saddr, void **p_data, signal_change_cb cb, const std::string &module_id) -{ - if(p_data == nullptr) - { - MY_LOG_E("p_data is nullptr"); - return -1; - } - - XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao); - if(p_signal != nullptr) - { - if(cb) - { - p_signal->change_cb_list.push_back({module_id, cb}); - } - - (*p_data) = p_signal->vec_p_data.empty() ? nullptr : p_signal->vec_p_data[0]; - return (*p_data) != nullptr ? 0 : -1; - } - - return -1; -} - -int dc_signal_ao_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, void *p_data, const std::string &module_id) -{ - if(p_data == nullptr) - { - MY_LOG_E("p_data is nullptr"); - return -1; - } - - XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao); - if(p_signal != nullptr) - { - if(0 == dc_check_ctrl_valid(p_signal, step, ctrl, p_data)) - { - if(0 != dc_check_val_valid(p_signal, 0, p_data)) - { - LOG_E("invalid value for saddr %s", saddr.c_str()); - - return -1; - } - - if(step == SIGNAL_CTRL_STEP::SELECT) - { - dc_set_signal_val(ctrl.p_data, ctrl.data_type, p_data); - ctrl.step = step; - } - else if(step == SIGNAL_CTRL_STEP::DIRECT) - { - dc_set_signal_val(p_signal->vec_p_data[0], ctrl.data_type, p_data); - ctrl.step = SIGNAL_CTRL_STEP::READY; - } - else if(step == SIGNAL_CTRL_STEP::CANCEL) - { - ctrl.step = SIGNAL_CTRL_STEP::READY; - } - else - { - LOG_E("invalid step %d", step); - return -1; - } - - for(auto &entry : p_signal->change_cb_list) - { - if(entry.second) - { - // 回路阻断:修改本信号的模块不回调自身 - if (entry.first == module_id) continue; - entry.second(saddr, step, ctrl.data_type, 0, p_data); - } - } - - dc_set_param_cfg_change(true); - - return 0; - } - else - { - LOG_E("saddr %s ctrl invalid", saddr.c_str()); - ctrl.step = SIGNAL_CTRL_STEP::READY; - return -1; - } - } - - LOG_E("saddr %s not found", saddr.c_str()); - - return -1; -} - -int dc_signal_ao_set_val_without_check(const std::string &saddr, uint8_t data_type, void *p_data, const std::string &module_id) -{ - if(p_data == nullptr) - { - MY_LOG_E("p_data is nullptr"); - return -1; - } - - XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao); - if(p_signal != nullptr && !p_signal->vec_p_data.empty() && p_signal->data_type == data_type && p_signal->vec_p_data[0]) - { - if(p_signal->data_type != data_type) - { - LOG_E("saddr %s data type %s(%d) not match ctrl data type %s(%d)", - saddr.c_str(), dc_get_data_type_str_by_id(p_signal->data_type), p_signal->data_type, dc_get_data_type_str_by_id(data_type), data_type); - return -1; - } - - if(0 != dc_check_val_valid(p_signal, 0, p_data)) - { - return -1; - } - - dc_set_signal_val(p_signal->vec_p_data[0], data_type, p_data); - dc_set_param_cfg_change(true); - - for(auto &entry : p_signal->change_cb_list) - { - if(entry.second) - { - if (entry.first == module_id) continue; - entry.second(saddr, SIGNAL_CTRL_STEP::DIRECT, data_type, 0, p_data); - } - } - - return 0; - } - else - { - // LOG_E("saddr %s, p_signal %p, vec_size %d, data_type %d,%d, p_data %p", saddr.c_str(), p_signal, p_signal->vec_p_data.size(), p_signal->data_type, data_type, p_signal->vec_p_data[0]); - } - - LOG_E("saddr %s not found in ao table", saddr.c_str()); - return -1; -} - -int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t data_type, uint8_t ctrl_type, void **p_data, int data_num, signal_change_cb cb, const std::string &module_id) -{ - // 先从参数表里解析,调用参数注册 - // 程序注册时,从参数表里去查找,同一个信息,使用参数表中的保存的数据值,在线程初始化时,通知所有链接此信号的信号 - // 注册时不在参数表中的,新增到动态表里,并保存到参数表里,使用缺省值 - - if(0 == data_num) - { - MY_LOG_E("data_num is 0"); - return -1; - } - - for(int i = 0; i < data_num; i++) - { - if(p_data[i] == nullptr) - { - LOG_E("p_data[%d] is nullptr", i); - return -1; - } - } - - XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param); - if(p_signal != nullptr) - { - // Always copy old values to new pointers when data type matches - if(p_signal->data_type == data_type) - { - size_t copy_num = (data_num < p_signal->vec_p_data.size()) ? data_num : p_signal->vec_p_data.size(); - for(size_t i = 0; i < copy_num; i++) - { - dc_set_signal_val(p_data[i], data_type, p_signal->vec_p_data[i]); - } - } - - // dc_set_signal_val(p_data, data_type, p_signal->p_data); - dc_set_param_cfg_change(true); - { - std::lock_guard lock(g_datacenter.signal_param.mtx); - - for(size_t i = 0; i < p_signal->vec_p_data.size(); i++) - { - dc_delete_signal_data(p_signal->vec_p_data[i], data_type); - } - - p_signal->vec_p_data.clear(); - - for(size_t i = 0; i < data_num; i++) - { - p_signal->vec_p_data.push_back(p_data[i]); - } - - p_signal->change_cb_list.push_back({module_id, cb}); - } - return 0; - } - - dc_set_param_cfg_change(true); - - stru_signal signal; - signal.hash = hash; - signal.saddr.assign(saddr); - signal.desc.assign(desc); - signal.data_type = data_type; - dc_signal_apply_metadata(signal); - signal.ctrl_type = ctrl_type; - - dc_signal_add_to_map(signal, g_datacenter.signal_param); - - p_signal = dc_find_signal(saddr, g_datacenter.signal_param); - if(p_signal != nullptr ) - { - for(size_t i = 0; i < data_num; i++) - { - p_signal->vec_p_data.push_back(p_data[i]); - - } - - if(cb) - { - p_signal->change_cb_list.push_back({module_id, cb}); - } - return 0; - } - - return -1; -} - -int dc_signal_param_link_with_callback(const std::string &saddr, void **p_data, int data_num, signal_change_cb cb, const std::string &module_id) -{ - XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param); - if(p_signal != nullptr) - { - if(cb) - { - p_signal->change_cb_list.push_back({module_id, cb}); - } - - for(size_t i = 0; i < p_signal->vec_p_data.size() && i < data_num; i++) - { - p_data[i] = p_signal->vec_p_data[i]; - } - return 0; - } - - return -1; -} - - -int dc_signal_param_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, uint8_t setting_zone, void *p_data, const std::string &module_id) -{ - if(p_data == nullptr) - { - MY_LOG_E("p_data is nullptr"); - return -1; - } - - XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param); - if(p_signal != nullptr) - { - if(0 == dc_check_ctrl_valid(p_signal, step, ctrl, p_data)) - { - if(0 != dc_check_val_valid(p_signal, setting_zone, p_data)) - { - LOG_E("invalid value for saddr %s", saddr.c_str()); - return -1; - } - - if(step == SIGNAL_CTRL_STEP::SELECT) - { - dc_set_signal_val(ctrl.p_data, ctrl.data_type, p_data); - ctrl.step = SIGNAL_CTRL_STEP::SELECT; - } - else if(step == SIGNAL_CTRL_STEP::DIRECT) - { - dc_set_signal_val(p_signal->vec_p_data[setting_zone], ctrl.data_type, p_data); - ctrl.step = SIGNAL_CTRL_STEP::READY; - } - else if(step == SIGNAL_CTRL_STEP::CANCEL) - { - ctrl.step = SIGNAL_CTRL_STEP::READY; - } - else - { - LOG_E("invalid ctrl step %d", step); - return -1; - } - - for(auto &entry : p_signal->change_cb_list) - { - if(entry.second != nullptr) - { - // 回路阻断:修改本信号的模块不回调自身 - if (entry.first == module_id) continue; - entry.second(saddr, step, ctrl.data_type, setting_zone, p_data); - } - } - - dc_set_param_cfg_change(true); - - return 0; - } - else - { - LOG_E("saddr %s ctrl invalid", saddr.c_str()); - ctrl.step = SIGNAL_CTRL_STEP::READY; - return -1; - } - } - - LOG_E("saddr %s not found in param table", saddr.c_str()); - - return -1; -} - -int dc_signal_param_set_val_without_check(const std::string &saddr, uint8_t data_type, uint8_t setting_zone, void *p_data, const std::string &module_id) -{ - if(p_data == nullptr) - { - MY_LOG_E("p_data is nullptr"); - return -1; - } - - XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param); - - if(p_signal != nullptr && setting_zone < p_signal->vec_p_data.size()) - { - if(p_signal->data_type != data_type) - { - LOG_E("saddr %s data type %s(%d) not match ctrl data type %s(%d)", - saddr.c_str(), dc_get_data_type_str_by_id(p_signal->data_type), p_signal->data_type, dc_get_data_type_str_by_id(data_type), data_type); - return -1; - } - - if(0 != dc_check_val_valid(p_signal, setting_zone, p_data)) - { - return -1; - } - dc_set_signal_val(p_signal->vec_p_data[setting_zone], data_type, p_data); - dc_set_param_cfg_change(true); - - for(auto &entry : p_signal->change_cb_list) - { - if(entry.second != nullptr) - { - if (entry.first == module_id) continue; - entry.second(saddr, SIGNAL_CTRL_STEP::DIRECT, data_type, setting_zone, p_data); - } - } - - return 0; - } - - LOG_E("saddr %s not found in param table", saddr.c_str()); - return -1; -} - -int dc_signal_yk(const std::string &saddr, const std::string &desc, uint8_t data_type, uint8_t ctrl_type, void *p_data, signal_change_cb cb, const std::string &module_id) -{ - if(p_data == nullptr) - { - MY_LOG_E("p_data is nullptr"); - return -1; - } - - stru_signal signal; - - signal.hash = XXH3_128bits(saddr.c_str(), saddr.length()); - signal.saddr.assign(saddr); - signal.desc.assign(desc); - signal.data_type = data_type; - signal.vec_p_data.push_back(p_data); - - dc_signal_add_to_map(signal, g_datacenter.signal_yk); - - stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_yk); - if(p_signal != nullptr) - { - if(cb) - { - p_signal->change_cb_list.push_back({module_id, cb}); - } - - p_signal->ctrl_type = ctrl_type; - - return 0; - } - - return -1; -} - -int dc_signal_yk_link_with_callback(const std::string &saddr, void **p_data, signal_change_cb cb, const std::string &module_id) -{ - if(p_data == nullptr) - { - MY_LOG_E("p_data is nullptr"); - return -1; - } - - XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_yk); - if(p_signal != nullptr) - { - if(cb) - { - p_signal->change_cb_list.push_back({module_id, cb}); - } - (*p_data) = p_signal->vec_p_data.empty() ? nullptr : p_signal->vec_p_data[0]; - return (*p_data) != nullptr ? 0 : -1; - } - - return -1; -} - -int dc_signal_yk_set_status(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, void *p_data, const std::string &module_id) -{ - if(p_data == nullptr) - { - MY_LOG_E("p_data is nullptr"); - return -1; - } - - XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_yk); - if(p_signal != nullptr) - { - if(0 == dc_check_ctrl_valid(p_signal, step, ctrl, p_data)) - { - if(0 != dc_check_yk_val_valid(p_signal, p_data)) - { - LOG_E("YK val check failed, saddr=%s", saddr.c_str()); - return -1; - } - - if(step == SIGNAL_CTRL_STEP::SELECT) - { - dc_set_signal_val(ctrl.p_data, ctrl.data_type, p_data); - ctrl.step = SIGNAL_CTRL_STEP::SELECT; - } - else if(step == SIGNAL_CTRL_STEP::DIRECT) - { - dc_set_signal_val(p_signal->vec_p_data[0], ctrl.data_type, p_data); - ctrl.step = SIGNAL_CTRL_STEP::READY; - } - else if(step == SIGNAL_CTRL_STEP::CANCEL) - { - ctrl.step = SIGNAL_CTRL_STEP::READY; - } - else - { - LOG_E("invalid ctrl step %d", step); - return -1; - } - - for(auto &entry : p_signal->change_cb_list) - { - if(entry.second != nullptr) - { - // 回路阻断:修改本信号的模块不回调自身 - if (entry.first == module_id) continue; - entry.second(saddr, step, ctrl.data_type, 0, p_data); - } - } - - return 0; - } - else - { - LOG_E("saddr %s ctrl invalid", saddr.c_str()); - ctrl.step = SIGNAL_CTRL_STEP::READY; - return -1; - } - } - - LOG_E("saddr %s not found in yk table", saddr.c_str()); - - return -1; -} - - -LOCAL stru_signal* dc_find_signal(const std::string &saddr, stru_signal_map &dc_signal_map) -{ - XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - std::lock_guard lock(dc_signal_map.mtx); - - auto range = dc_signal_map.map_signals.equal_range(hash); - for (auto it = range.first; it != range.second; ++it) { - if (it->second.saddr == saddr) { - return &it->second; - } - } - return nullptr; -} - - -LOCAL stru_signal* dc_find_out_signal(const std::string &saddr) -{ - return dc_find_signal(saddr, g_datacenter.signal_out); -} - -LOCAL stru_signal* dc_find_in_signal(const std::string &saddr) -{ - return dc_find_signal(saddr, g_datacenter.signal_in); -} - -LOCAL std::map g_data_type_str = { - {DATA_TYPE_B, "bool"}, - {DATA_TYPE_S8, "int8_t"}, - {DATA_TYPE_U8, "uint8_t"}, - {DATA_TYPE_S16, "int16_t"}, - {DATA_TYPE_U16, "uint16_t"}, - {DATA_TYPE_S32, "int32_t"}, - {DATA_TYPE_U32, "uint32_t"}, - {DATA_TYPE_L64, "int64_t"}, - {DATA_TYPE_UL64, "uint64_t"}, - {DATA_TYPE_F32, "float"}, - {DATA_TYPE_D64, "double"}, - {DATA_TYPE_IP, "ip"}, - {DATA_TYPE_MAC, "mac"}, - {DATA_TYPE_C8, "char8"}, - {DATA_TYPE_C32, "char32"}, - {DATA_TYPE_C64, "char64"}, - {DATA_TYPE_C128, "char128"}, - {DATA_TYPE_C1, "char1"}, - {DATA_TYPE_STR, "str"} -}; - -LOCAL std::map g_data_type_len = { - {DATA_TYPE_B, 1}, - {DATA_TYPE_S8, 1}, - {DATA_TYPE_U8, 1}, - {DATA_TYPE_S16, 2}, - {DATA_TYPE_U16, 2}, - {DATA_TYPE_S32, 4}, - {DATA_TYPE_U32, 4}, - {DATA_TYPE_L64, 8}, - {DATA_TYPE_UL64, 8}, - {DATA_TYPE_F32, 4}, - {DATA_TYPE_D64, 8}, - {DATA_TYPE_IP, 4}, - {DATA_TYPE_MAC, 8}, - {DATA_TYPE_C8, 8}, - {DATA_TYPE_C32, 32}, - {DATA_TYPE_C64, 64}, - {DATA_TYPE_C128, 128}, - {DATA_TYPE_C1, 1}, - {DATA_TYPE_STR, 128} -}; - -std::string dc_get_data_type_str_by_id(uint8_t data_type) -{ - auto it = g_data_type_str.find(data_type); - if(it != g_data_type_str.end()) - { - return it->second; - } - else - { - return "unknown"; - } -} - -uint8_t dc_get_data_type_id_by_str(const std::string &data_type_str) -{ - for(const auto &p : g_data_type_str) - { - if(p.second.compare(data_type_str) == 0) - { - return p.first; - } - } - return 0; -} - -uint8_t dc_get_data_type_len(uint8_t data_type) -{ - auto it = g_data_type_len.find(data_type); - if(it != g_data_type_len.end()) - { - return it->second; - } - else - { - return 0; - } -} - -std::string dc_get_signal_val(void *p_data, uint8_t data_type) -{ - if(NULL == p_data) - { - MY_LOG_E("p_data is nullptr"); - return ""; - } - - std::string str = ""; - char temp[128] = {0}; - char *ptr = NULL; - - switch(data_type) - { - case DATA_TYPE_B: - str = (*(int8_t *)p_data) > 0 ? "true" : "false"; - break; - case DATA_TYPE_S8: - str = std::to_string(*(int8_t *)p_data); - break; - case DATA_TYPE_U8: - str = std::to_string(*(uint8_t*)p_data); - break; - case DATA_TYPE_S16: - str = std::to_string(*(int16_t *)p_data); - break; - case DATA_TYPE_U16: - str = std::to_string(*(uint16_t*)p_data); - break; - case DATA_TYPE_S32: - str = std::to_string(*(int32_t *)p_data); - break; - case DATA_TYPE_U32: - str = std::to_string(*(uint32_t*)p_data); - break; - case DATA_TYPE_L64: - str = std::to_string(*(int64_t *)p_data); - break; - case DATA_TYPE_UL64: - str = std::to_string(*(uint64_t*)p_data); - break; - case DATA_TYPE_F32: - str = std::to_string(*(float*)p_data); - break; - case DATA_TYPE_D64: - str = std::to_string(*(double*)p_data); - break; - case DATA_TYPE_IP: - ptr = (char *)p_data; - snprintf(temp, 32, "%d.%d.%d.%d", (uint8_t)ptr[0], (uint8_t)ptr[1], (uint8_t)ptr[2], (uint8_t)ptr[3]); - str = std::string(temp); - break; - case DATA_TYPE_MAC: - ptr = (char *)p_data; - snprintf(temp, 32, "%02X:%02X:%02X:%02X:%02X:%02X", (uint8_t)ptr[0], (uint8_t)ptr[1], (uint8_t)ptr[2], (uint8_t)ptr[3], (uint8_t)ptr[4], (uint8_t)ptr[5]); - str = std::string(temp); - break; - case DATA_TYPE_C8: - case DATA_TYPE_C32: - case DATA_TYPE_C64: - case DATA_TYPE_C128: - // str = (char *)p_data; - snprintf(temp, dc_get_data_type_len(data_type), "%s", (char *)p_data); - str = std::string(temp); - break; - case DATA_TYPE_C1: - str = std::string(1, *(char*)p_data); - break; - case DATA_TYPE_STR: - snprintf(temp, dc_get_data_type_len(data_type), "%s", (char *)p_data); - str = std::string(temp); - break; - default: - break; - } - - return str; -} - -LOCAL int dc_set_signal_val(void *p_data, uint8_t data_type, void *set_data) -{ - if(NULL == p_data || NULL == set_data) - { - LOG_E("p_data or str is NULL, p_data: %p, set_data: %p", p_data, set_data); - return -1; - } - - switch(data_type) - { - case DATA_TYPE_B: - *(int8_t *)p_data = ((char *)set_data)[0] & 0x01; - break; - case DATA_TYPE_S8: - *(int8_t *)p_data = *(int8_t *)set_data; - break; - case DATA_TYPE_U8: - *(uint8_t*)p_data = *(uint8_t*)set_data; - break; - case DATA_TYPE_S16: - *(int16_t *)p_data = *(int16_t *)set_data; - break; - case DATA_TYPE_U16: - *(uint16_t*)p_data = *(uint16_t*)set_data; - break; - case DATA_TYPE_S32: - *(int32_t *)p_data = *(int32_t *)set_data; - break; - case DATA_TYPE_U32: - *(uint32_t*)p_data = *(uint32_t*)set_data; - break; - case DATA_TYPE_L64: - *(int64_t *)p_data = *(int64_t *)set_data; - break; - case DATA_TYPE_UL64: - *(uint64_t*)p_data = *(uint64_t*)set_data; - break; - case DATA_TYPE_F32: - *(float*)p_data = *(float*)set_data; - break; - case DATA_TYPE_D64: - *(double*)p_data = *(double*)set_data; - break; - case DATA_TYPE_IP: - memcpy(p_data, set_data, 4); - break; - case DATA_TYPE_MAC: - memcpy(p_data, set_data, 6); - break; - case DATA_TYPE_C8: - case DATA_TYPE_C32: - case DATA_TYPE_C64: - case DATA_TYPE_C128: - case DATA_TYPE_STR: - memcpy(p_data, set_data, dc_get_data_type_len(data_type)); - break; - case DATA_TYPE_C1: - *(char*)p_data = *(char*)set_data; - break; - default: - LOG_E("unknown data_type: %d", data_type); - return -1; - } - - return 0; -} - -void dc_set_signal_val_from_str(void *p_data, uint8_t data_type, const std::string &str) -{ - if (str.empty() || p_data == nullptr) - { - MY_LOG_E("str is empty or p_data is nullptr"); - return; - } - - switch (data_type) - { - case DATA_TYPE_B: - *(uint8_t *)p_data = (str == "true" || str == "1") ? 1 : 0; - break; - case DATA_TYPE_S8: - *(int8_t *)p_data = (int8_t)std::stoi(str); - break; - case DATA_TYPE_U8: - *(uint8_t *)p_data = (uint8_t)std::stoul(str); - break; - case DATA_TYPE_S16: - *(int16_t *)p_data = (int16_t)std::stoi(str); - break; - case DATA_TYPE_U16: - *(uint16_t *)p_data = (uint16_t)std::stoul(str); - break; - case DATA_TYPE_S32: - *(int32_t *)p_data = std::stoi(str); - break; - case DATA_TYPE_U32: - *(uint32_t *)p_data = std::stoul(str); - break; - case DATA_TYPE_L64: - *(int64_t *)p_data = std::stoll(str); - break; - case DATA_TYPE_UL64: - *(uint64_t *)p_data = std::stoull(str); - break; - case DATA_TYPE_F32: - *(float *)p_data = std::stof(str); - break; - case DATA_TYPE_D64: - *(double *)p_data = std::stod(str); - break; - case DATA_TYPE_IP: - { - int a, b, c, d; - if (4 == sscanf(str.c_str(), "%d.%d.%d.%d", &a, &b, &c, &d)) - { - ((uint8_t *)p_data)[0] = (uint8_t)a; - ((uint8_t *)p_data)[1] = (uint8_t)b; - ((uint8_t *)p_data)[2] = (uint8_t)c; - ((uint8_t *)p_data)[3] = (uint8_t)d; - } - } - break; - case DATA_TYPE_MAC: - { - int m[6]; - if (6 == sscanf(str.c_str(), "%02X:%02X:%02X:%02X:%02X:%02X", &m[0], &m[1], &m[2], &m[3], &m[4], &m[5])) - { - for (int i = 0; i < 6; i++) - ((uint8_t *)p_data)[i] = (uint8_t)m[i]; - } - } - break; - case DATA_TYPE_C8: - case DATA_TYPE_C32: - case DATA_TYPE_C64: - case DATA_TYPE_C128: - case DATA_TYPE_STR: - strncpy((char *)p_data, str.c_str(), dc_get_data_type_len(data_type)); - break; - case DATA_TYPE_C1: - *(char *)p_data = str[0]; - break; - default: - LOG_E("unknown data_type: %d", data_type); - break; - } -} - -int dc_set_out_signal_val(const std::string &saddr, void *set_data, const std::string &module_id) -{ - stru_signal *p_signal = dc_find_out_signal(saddr); - if(p_signal != nullptr) - { - p_signal->last_caller_module = module_id; - dc_mark_signal_dirty(p_signal); - return dc_set_signal_val(p_signal->vec_p_data[0], p_signal->data_type, set_data); - } - - return -1; -} - -void *dc_create_data_ptr_by_type(uint8_t data_type) -{ - uint8_t *p_u8 = nullptr; - int8_t *p_s8 = nullptr; - int16_t *p_s16 = nullptr; - uint16_t *p_u16 = nullptr; - int32_t *p_s32 = nullptr; - uint32_t *p_u32 = nullptr; - int64_t *p_l64 = nullptr; - uint64_t *p_ul64 = nullptr; - float *p_f = nullptr; - double *p_d = nullptr; - char *p_char = nullptr; - - switch(data_type) - { - case DATA_TYPE_B: - p_u8 = new uint8_t; - (*p_u8) = 0; - return p_u8; - case DATA_TYPE_S8: - p_s8 = new int8_t; - (*p_s8) = 0; - return p_s8; - case DATA_TYPE_U8: - p_u8 = new uint8_t; - (*p_u8) = 0; - return p_u8; - case DATA_TYPE_S16: - p_s16 = new int16_t; - (*p_s16) = 0; - return p_s16; - case DATA_TYPE_U16: - p_u16 = new uint16_t; - (*p_u16) = 0; - return p_u16; - case DATA_TYPE_S32: - p_s32 = new int32_t; - (*p_s32) = 0; - return p_s32; - case DATA_TYPE_U32: - p_u32 = new uint32_t; - (*p_u32) = 0; - return p_u32; - case DATA_TYPE_L64: - p_l64 = new int64_t; - (*p_l64) = 0; - return p_l64; - case DATA_TYPE_UL64: - p_ul64 = new uint64_t; - (*p_ul64) = 0; - return p_ul64; - case DATA_TYPE_F32: - p_f = new float; - (*p_f) = 0.0; - return p_f; - case DATA_TYPE_D64: - p_d = new double; - (*p_d) = 0.0; - return p_d; - case DATA_TYPE_IP: - p_char = new char[4]; - memset(p_char, 0, 4); - return p_char; - case DATA_TYPE_MAC: - p_char = new char[8]; - memset(p_char, 0, 8); - return p_char; - case DATA_TYPE_C8: - p_char = new char[8]; - memset(p_char, 0, 8); - return p_char; - case DATA_TYPE_C32: - p_char = new char[32]; - memset(p_char, 0, 32); - return p_char; - case DATA_TYPE_C64: - p_char = new char[64]; - memset(p_char, 0, 64); - return p_char; - case DATA_TYPE_C128: - p_char = new char[128]; - memset(p_char, 0, 128); - return p_char; - case DATA_TYPE_C1: - p_char = new char[1]; - memset(p_char, 0, 1); - return p_char; - case DATA_TYPE_STR: - p_char = new char[128]; - memset(p_char, 0, 128); - return p_char; - default: - LOG_E("unknown data_type: %d", data_type); - return nullptr; - } -} - -void dc_delete_signal_data(void *p_data, uint8_t data_type) -{ - if(nullptr == p_data) return; - - switch(data_type) - { - case DATA_TYPE_B: - delete static_cast(p_data); - break; - case DATA_TYPE_S8: - delete static_cast(p_data); - break; - case DATA_TYPE_U8: - delete static_cast(p_data); - break; - case DATA_TYPE_S16: - delete static_cast(p_data); - break; - case DATA_TYPE_U16: - delete static_cast(p_data); - break; - case DATA_TYPE_S32: - delete static_cast(p_data); - break; - case DATA_TYPE_U32: - delete static_cast(p_data); - break; - case DATA_TYPE_L64: - delete static_cast(p_data); - break; - case DATA_TYPE_UL64: - delete static_cast(p_data); - break; - case DATA_TYPE_F32: - delete static_cast(p_data); - break; - case DATA_TYPE_D64: - delete static_cast(p_data); - break; - case DATA_TYPE_IP: - case DATA_TYPE_MAC: - case DATA_TYPE_C8: - case DATA_TYPE_C32: - case DATA_TYPE_C64: - case DATA_TYPE_C128: - case DATA_TYPE_C1: - case DATA_TYPE_STR: - delete [] static_cast(p_data); - break; - default: - MY_LOG_E("Unknown data_type %d for delete", data_type); - break; - } -} - - -LOCAL stru_signal *dc_find_signal_by_id(uint32_t id, stru_signal_map &dc_signal_map) -{ - if (id < dc_signal_map.id_index.size()) - return dc_signal_map.id_index[id]; - return nullptr; -} - - -void dc_param_cfg_check(const std::string &path) -{ - if (false == dc_get_param_cfg_change()) return; - - using namespace tinyxml2; - - XMLDocument doc; - doc.InsertEndChild(doc.NewDeclaration()); - - XMLElement *root = doc.NewElement("Root"); - doc.InsertEndChild(root); - - int ao_no = 0, param_no = 0; - - XMLElement *ao_elem = doc.NewElement("Ao"); - - // for(auto it = g_datacenter.signal_ao.map_signals.begin(); it != g_datacenter.signal_ao.map_signals.end(); it++) - for(uint32_t i = 0; i < g_datacenter.signal_ao.signal_id; i++) - { - stru_signal *p_ao = dc_find_signal_by_id(i, g_datacenter.signal_ao); - if(nullptr == p_ao) - { - MY_LOG_E("ao id %d not found", i); - continue; - } - - XMLElement *sig_elem = doc.NewElement("Signal"); - sig_elem->SetAttribute("id", p_ao->id); - sig_elem->SetAttribute("saddr", p_ao->saddr.c_str()); - sig_elem->SetAttribute("desc", p_ao->desc.c_str()); - sig_elem->SetAttribute("type", dc_get_data_type_str_by_id(p_ao->data_type).c_str()); - sig_elem->SetAttribute("min", p_ao->param.min); - sig_elem->SetAttribute("max", p_ao->param.max); - sig_elem->SetAttribute("step", p_ao->param.step); - sig_elem->SetAttribute("unit", p_ao->param.unit.c_str()); - sig_elem->SetAttribute("value", dc_get_signal_val(p_ao->vec_p_data[0], p_ao->data_type).c_str()); - - ao_elem->InsertEndChild(sig_elem); - } - - XMLElement *param_elem = doc.NewElement("Param"); - - // for(auto it = g_datacenter.signal_param.map_signals.begin(); it != g_datacenter.signal_param.map_signals.end(); it++) - for(uint32_t i = 0; i < g_datacenter.signal_param.signal_id; i++) - { - stru_signal *p_param = dc_find_signal_by_id(i, g_datacenter.signal_param); - if(nullptr == p_param) - { - MY_LOG_E("param id %d not found", i); - continue; - } - - XMLElement *sig_elem = doc.NewElement("Signal"); - sig_elem->SetAttribute("saddr", p_param->saddr.c_str()); - sig_elem->SetAttribute("desc", p_param->desc.c_str()); - sig_elem->SetAttribute("type", dc_get_data_type_str_by_id(p_param->data_type).c_str()); - sig_elem->SetAttribute("min", p_param->param.min); - sig_elem->SetAttribute("max", p_param->param.max); - sig_elem->SetAttribute("step", p_param->param.step); - sig_elem->SetAttribute("unit", p_param->param.unit.c_str()); - sig_elem->SetAttribute("num", p_param->vec_p_data.size()); - - - for(int i = 0; i < p_param->vec_p_data.size(); i++) - { - std::string val = dc_get_signal_val(p_param->vec_p_data[i], p_param->data_type); - - XMLElement *item_elem = doc.NewElement("Item"); - item_elem->SetAttribute("index", i+1); - item_elem->SetAttribute("value", val.c_str()); - - sig_elem->InsertEndChild(item_elem); - } - - param_elem->InsertEndChild(sig_elem); - } - - root->InsertEndChild(ao_elem); - root->InsertEndChild(param_elem); - - // 保存到 self_param.xml,不覆盖参数模板 param.xml - std::string self_path = path; - size_t pos = self_path.rfind("param.xml"); - if (pos != std::string::npos) - self_path.replace(pos, 9, "self_param.xml"); - - if (XML_SUCCESS == doc.SaveFile(self_path.c_str())) - { - dc_set_param_cfg_change(false); - MY_LOG_I("param runtime saved to %s", self_path.c_str()); - } - else - { - MY_LOG_E("failed to save param runtime to %s", self_path.c_str()); - } -} - - -LOCAL void dc_show_signals(stru_signal_map &dc_signal_map) -{ - using namespace std; - - hash_signal_map &signal_map = dc_signal_map.map_signals; - - // 定义列宽(单位:终端视觉列数,中文占2列,ASCII占1列) - const int COL_ID = 8; - const int COL_SADDR = 36; - const int COL_DESC = 48; - const int COL_TYPE = 10; - const int COL_VAL = 24; - const int COL_LINK = 48; - - // 按终端视觉宽度左对齐辅助函数 - auto visual_width = [](const std::string &s) -> int { - int w = 0; - for (size_t i = 0; i < s.size();) { - unsigned char c = s[i]; - if (c < 0x80) { w += 1; i += 1; } - else if (c < 0xC0) { i += 1; } // 连续字节不计宽 - else if (c < 0xE0) { w += 2; i += 2; } // 2字节字符 - else if (c < 0xF0) { w += 2; i += 3; } // CJK 3字节 - else { w += 2; i += 4; } // 4字节字符 - } - return w; - }; - auto pad_left = [&](const std::string &s, int width) -> std::string { - int vw = visual_width(s); - int pad = width - vw; - if (pad > 0) return s + std::string(pad, ' '); - return s + ' '; - }; - - // 打印表头 - cout << "\t" - << pad_left("id", COL_ID) - << pad_left("saddr", COL_SADDR) - << pad_left("desc", COL_DESC) - << pad_left("type", COL_TYPE) - << pad_left("val", COL_VAL) - << pad_left("link_saddrs", COL_LINK) - << endl; - - // 打印分隔线 - int total_width = COL_ID + COL_SADDR + COL_DESC + COL_TYPE + COL_VAL + COL_LINK; - cout << "\t" << string(total_width, '-') << endl; - - // 遍历信号表 - // for(auto it = signal_map.begin(); it != signal_map.end(); ++it) - for(uint32_t i = 0; i < dc_signal_map.signal_id; i++) - { - // const stru_signal *p_signal = &it->second; - stru_signal *p_signal = dc_find_signal_by_id(i, dc_signal_map); - if(nullptr == p_signal) - { - MY_LOG_E("signal id %d not found", i); - continue; - } - - // 1. 先把所有列的内容拼接成字符串,再一次性输出,避免中间打断对齐 - string link_str; - bool first = true; - for (const auto &link : p_signal->link_saddrs) - { - if (!first) link_str += ", "; - link_str += link; - first = false; - } - - std::string val_str = dc_get_signal_val(p_signal->vec_p_data[0], p_signal->data_type); - - // 2. 输出所有列,按视觉宽度对齐 - cout << "\t" - << pad_left(std::to_string(p_signal->id), COL_ID) - << pad_left(p_signal->saddr, COL_SADDR) - << pad_left(p_signal->desc, COL_DESC) - << pad_left(dc_get_data_type_str_by_id(p_signal->data_type), COL_TYPE) - << pad_left(val_str, COL_VAL) - << pad_left(link_str, COL_LINK) - << endl; - - if (!cout.good()) break; - } - - if (!cout.good()) return; - - cout << endl; - - cout << "signal_id: " << dc_signal_map.signal_id << endl; - cout << "signal count: " << signal_map.size() << endl; - - cout << endl; -} - -uint32_t dc_get_signal_count(const char *type) -{ - if(nullptr == type) return 0; - if(0 == strcmp(type, "out")) return g_datacenter.signal_out.signal_id; - if(0 == strcmp(type, "in")) return g_datacenter.signal_in.signal_id; - if(0 == strcmp(type, "yk")) return g_datacenter.signal_yk.signal_id; - if(0 == strcmp(type, "ao")) return g_datacenter.signal_ao.signal_id; - if(0 == strcmp(type, "param")) return g_datacenter.signal_param.signal_id; - return 0; -} - -int dc_get_signal_info_by_id(const char *type, uint32_t id, std::string &saddr, std::string &desc, std::string &data_type, uint8_t &ctrl_type, std::vector &link_saddrs) -{ - if(nullptr == type) return -1; - - stru_signal *p_signal = nullptr; - if(0 == strcmp(type, "out")) p_signal = dc_find_signal_by_id(id, g_datacenter.signal_out); - if(0 == strcmp(type, "in")) p_signal = dc_find_signal_by_id(id, g_datacenter.signal_in); - if(0 == strcmp(type, "yk")) p_signal = dc_find_signal_by_id(id, g_datacenter.signal_yk); - if(0 == strcmp(type, "ao")) p_signal = dc_find_signal_by_id(id, g_datacenter.signal_ao); - if(0 == strcmp(type, "param")) p_signal = dc_find_signal_by_id(id, g_datacenter.signal_param); - if(nullptr == p_signal) - { - MY_LOG_E("signal id %d not found", id); - return -1; - } - - saddr = p_signal->saddr; - desc = p_signal->desc; - data_type = dc_get_data_type_str_by_id(p_signal->data_type); - ctrl_type = p_signal->ctrl_type; - link_saddrs = p_signal->link_saddrs; - return 0; -} - -LOCAL void dc_show_out_signals() -{ - using namespace std; - cout << "out signals: " << endl; - dc_show_signals(g_datacenter.signal_out); -} - -LOCAL void dc_show_in_signals() -{ - using namespace std; - - cout << "in signals: " << endl; - dc_show_signals(g_datacenter.signal_in); -} - -LOCAL void dc_show_yk_signals() -{ - using namespace std; - - cout << "yk signals: " << endl; - dc_show_signals(g_datacenter.signal_yk); -} - -LOCAL void dc_show_ao_signals() -{ - using namespace std; - - cout << "ao signals: " << endl; - dc_show_signals(g_datacenter.signal_ao); -} - - - -LOCAL void dc_show_param_signals() -{ - using namespace std; - - cout << "param signals: " << endl; - dc_show_signals(g_datacenter.signal_param); -} - - - -LOCAL void cmd_dc(int argc, char *argv[]) -{ - const char *str = "\ - datacenter out ----------> 查看out信号信息\n\ - datacenter in ----------> 查看in信号信息\n\ - datacenter yk ----------> 查看yk信号信息\n\ - datacenter ao ----------> 查看ao信号信息\n\ - datacenter param ----------> 查看param信号信息\n\ - datacenter all ----------> 查看所有信号信息\n"; - - - if(argc < 2) - { - printf("%s", str); - return; - } - - if(0 == strcmp(argv[1], "out")) - { - dc_show_out_signals(); - } - else if(0 == strcmp(argv[1], "in")) - { - dc_show_in_signals(); - } - else if(0 == strcmp(argv[1], "yk")) - { - dc_show_yk_signals(); - } - else if(0 == strcmp(argv[1], "ao")) - { - dc_show_ao_signals(); - } - else if(0 == strcmp(argv[1], "param")) - { - dc_show_param_signals(); - } - else if(0 == strcmp(argv[1], "all")) - { - dc_show_out_signals(); - dc_show_in_signals(); - dc_show_yk_signals(); - dc_show_ao_signals(); - dc_show_param_signals(); - } -} - -LOCAL void cmd_dc_complete(const char *buf, char ***completions, int *ncomp) -{ - static const char *subs[] = {"out", "in", "yk", "ao", "param", "all"}; - cmd_sub_complete(buf, completions, ncomp, subs, sizeof(subs)/sizeof(subs[0])); -} - -CMD_REGISTER_C("datacenter", cmd_dc, "数据中心的控制命令", cmd_dc_complete); - - diff --git a/src/public/libdatacenter/src/dc_signal_compare.cpp b/src/public/libdatacenter/src/dc_signal_compare.cpp new file mode 100644 index 0000000..835267e --- /dev/null +++ b/src/public/libdatacenter/src/dc_signal_compare.cpp @@ -0,0 +1,81 @@ +#include "dc_signal_internal.h" +int dc_data_compare(uint8_t data_type, void *p_data, void *p_data2) +{ + if(p_data == nullptr || p_data2 == nullptr) + { + LOG_E("p_data or p_data2 is nullptr"); + return -1; + } + + float f1 = 0.0f; + float f2 = 0.0f; + double d1 = 0.0; + double d2 = 0.0; + + switch(data_type) + { + case DATA_TYPE_B: + case DATA_TYPE_U8: + return (*(uint8_t *)p_data == *(uint8_t *)p_data2) ? 0 : -1; + case DATA_TYPE_S8: + return (*(int8_t *)p_data == *(int8_t *)p_data2) ? 0 : -1; + case DATA_TYPE_S16: + return (*(int16_t *)p_data == *(int16_t *)p_data2) ? 0 : -1; + case DATA_TYPE_U16: + return (*(uint16_t *)p_data == *(uint16_t *)p_data2) ? 0 : -1; + case DATA_TYPE_S32: + return (*(int32_t *)p_data == *(int32_t *)p_data2) ? 0 : -1; + case DATA_TYPE_U32: + return (*(uint32_t *)p_data == *(uint32_t *)p_data2) ? 0 : -1; + case DATA_TYPE_L64: + return (*(int64_t *)p_data == *(int64_t *)p_data2) ? 0 : -1; + case DATA_TYPE_UL64: + return (*(uint64_t *)p_data == *(uint64_t *)p_data2) ? 0 : -1; + case DATA_TYPE_F32: + f1 = *(float *)p_data; + f2 = *(float *)p_data2; + return f1 == f2 ? 0 : -1; + case DATA_TYPE_D64: + d1 = *(double *)p_data; + d2 = *(double *)p_data2; + return d1 == d2 ? 0 : -1; + case DATA_TYPE_C1: + return (*(char *)p_data == *(char *)p_data2) ? 0 : -1; + case DATA_TYPE_IP: + case DATA_TYPE_MAC: + case DATA_TYPE_C8: + case DATA_TYPE_C32: + case DATA_TYPE_C64: + case DATA_TYPE_C128: + case DATA_TYPE_STR: + return (0 == strcmp((char *)p_data, (char *)p_data2)) ? 0 : -1; + default: + LOG_E("unsupported data type %d", data_type); + return -1; + } + + return -1; +} + + +// 从中央元数据表查找并设置 signal.param +void dc_signal_apply_metadata(stru_signal &signal) +{ + stru_signal_param param; + if (dc_param_metadata_lookup(signal.saddr, param)) + { + signal.param = param; + } + else + { + signal.param.min = 0.0f; + signal.param.max = 0.0f; + signal.param.step = 0.0f; + signal.param.unit.clear(); + } +} + + + + + diff --git a/src/public/libdatacenter/src/dc_signal_core.cpp b/src/public/libdatacenter/src/dc_signal_core.cpp new file mode 100644 index 0000000..1a6359f --- /dev/null +++ b/src/public/libdatacenter/src/dc_signal_core.cpp @@ -0,0 +1,765 @@ +#include "dc_signal_internal.h" +int dc_signal_add_to_map(stru_signal &signal, stru_signal_map &dc_signal_map) +{ + std::lock_guard lock(dc_signal_map.mtx); + + // 先查找是否已有相同 saddr 的信号(更新场景) + auto range = dc_signal_map.map_signals.equal_range(signal.hash); + for (auto it = range.first; it != range.second; ++it) { + if (it->second.saddr == signal.saddr) { + // 已有相同 saddr,更新内容,保留 id + uint32_t old_id = it->second.id; + it->second = signal; + it->second.id = old_id; + return 0; + } + } + + // 新信号,插入 multimap + auto it = dc_signal_map.map_signals.emplace(signal.hash, signal); + it->second.id = dc_signal_map.signal_id++; + if (dc_signal_map.id_index.size() <= it->second.id) { + dc_signal_map.id_index.resize(it->second.id + 1, nullptr); + } + dc_signal_map.id_index[it->second.id] = &it->second; + + return 0; +} + + +int dc_signal_out(const std::string &saddr, const std::string &desc, uint8_t data_type, void *p_data) +{ + if(p_data == nullptr) + { + MY_LOG_E("p_data is nullptr"); + return -1; + } + + stru_signal *p_signal = dc_find_out_signal(saddr); + if(nullptr != p_signal) + { + MY_LOG_E("saddr %s already registered", saddr.c_str()); + return -1; + } + + stru_signal signal; + + signal.hash = XXH3_128bits(saddr.c_str(), saddr.length()); + signal.saddr.assign(saddr); + signal.desc.assign(desc); + signal.data_type = data_type; + signal.vec_p_data.push_back(p_data); + void *p_last_data = dc_create_data_ptr_by_type(data_type); + if(p_last_data == nullptr) + { + MY_LOG_E("create p_last_data failed"); + return -1; + } + signal.p_last_data = p_last_data; + + // MY_LOG_I("saddr %s, p_data %p", saddr.c_str(), p_data); + return dc_signal_add_to_map(signal, g_datacenter.signal_out); +} + +int dc_signal_out_with_callback(const std::string &saddr, const std::string &desc, uint8_t data_type, void *p_data, out_signal_change_cb cb, const std::string &module_id) +{ + if(nullptr == p_data) + { + MY_LOG_E("p_data is nullptr"); + return -1; + } + + stru_signal *p_signal = dc_find_out_signal(saddr); + if(nullptr != p_signal) + { + MY_LOG_E("saddr %s already registered", saddr.c_str()); + return -1; + } + + stru_signal signal; + signal.hash = XXH3_128bits(saddr.c_str(), saddr.length()); + signal.saddr.assign(saddr); + signal.desc.assign(desc); + signal.data_type = data_type; + signal.vec_p_data.push_back(p_data); + void *p_last_data = dc_create_data_ptr_by_type(data_type); + if(p_last_data == nullptr) + { + MY_LOG_E("create p_last_data failed"); + return -1; + } + signal.p_last_data = p_last_data; + if(nullptr != cb) + { + signal.out_change_cb_list.push_back({module_id, cb}); + } + + return dc_signal_add_to_map(signal, g_datacenter.signal_out); +} + +int dc_signal_out_link_with_callback(const std::string &saddr, void **p_data, out_signal_change_cb cb, const std::string &module_id) +{ + stru_signal *p_signal = dc_find_out_signal(saddr); + if(nullptr == p_signal) + { + MY_LOG_E("saddr %s not found", saddr.c_str()); + return -1; + } + + if(p_signal->vec_p_data.empty() || nullptr == p_signal->vec_p_data[0]) + { + MY_LOG_E("saddr %s vec_p_data is empty or vec_p_data[0] is nullptr", saddr.c_str()); + return -1; + } + + if(p_data != nullptr) + { + (*p_data) = p_signal->vec_p_data[0]; + } + + if(nullptr != cb) + { + p_signal->out_change_cb_list.push_back({module_id, cb}); + } + + return 0; +} + +int dc_signal_in(const std::string &saddr, const std::string &desc, const std::string &link_saddr, void **p_data) +{ + if(p_data == nullptr) + { + MY_LOG_E("p_data is nullptr"); + return -1; + } + + stru_signal *p_signal = dc_find_in_signal(saddr); + if(nullptr != p_signal) + { + MY_LOG_E("saddr %s already registered", saddr.c_str()); + return -1; + } + + stru_signal signal; + + signal.hash = XXH3_128bits(saddr.c_str(), saddr.length()); + signal.saddr.assign(saddr); + signal.desc.assign(desc); + + if(link_saddr.empty()) + { + MY_LOG_E("link_saddr is empty"); + return -1; + } + + stru_signal *p_signal_out = dc_find_out_signal(link_saddr); + if(p_signal_out == nullptr) + { + MY_LOG_E("link_saddr %s not found", link_saddr.c_str()); + return -1; + } + + (*p_data) = p_signal_out->vec_p_data[0]; + signal.data_type = p_signal_out->data_type; + signal.vec_p_data.push_back((*p_data)); + + if(p_signal_out->link_set.find(saddr) == p_signal_out->link_set.end()) + { + p_signal_out->link_set.insert(saddr); + p_signal_out->link_saddrs.push_back(saddr); + } + + signal.link_saddrs.push_back(link_saddr); + + return dc_signal_add_to_map(signal, g_datacenter.signal_in); +} + +int dc_signal_in_with_callback(const std::string &saddr, const std::string &desc, const std::string &link_saddr, void **p_data, out_signal_change_cb cb, const std::string &module_id) +{ + if(p_data == nullptr) + { + MY_LOG_E("p_data is nullptr"); + return -1; + } + + stru_signal *p_signal = dc_find_in_signal(saddr); + if(nullptr != p_signal) + { + MY_LOG_E("saddr %s already registered", saddr.c_str()); + return -1; + } + + stru_signal signal; + signal.hash = XXH3_128bits(saddr.c_str(), saddr.length()); + signal.saddr.assign(saddr); + signal.desc.assign(desc); + + if(link_saddr.empty()) + { + MY_LOG_E("link_saddr is empty"); + return -1; + } + + stru_signal *p_signal_out = dc_find_out_signal(link_saddr); + if(p_signal_out == nullptr) + { + MY_LOG_E("link_saddr %s not found", link_saddr.c_str()); + return -1; + } + + (*p_data) = p_signal_out->vec_p_data[0]; + signal.data_type = p_signal_out->data_type; + signal.vec_p_data.push_back((*p_data)); + + if(nullptr != cb) + { + p_signal_out->out_change_cb_list.push_back({module_id, cb}); + } + + if(p_signal_out->link_set.find(saddr) == p_signal_out->link_set.end()) + { + p_signal_out->link_set.insert(saddr); + p_signal_out->link_saddrs.push_back(saddr); + } + + signal.link_saddrs.push_back(link_saddr); + + return dc_signal_add_to_map(signal, g_datacenter.signal_in); +} + +int dc_signal_ao(const std::string &saddr, const std::string &desc, uint8_t data_type, uint8_t ctrl_type, void *p_data, signal_change_cb cb, const std::string &module_id) +{ + if(p_data == nullptr) + { + MY_LOG_E("p_data is nullptr"); + return -1; + } + + XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao); + if(p_signal != nullptr && !p_signal->vec_p_data.empty() && nullptr != p_signal->vec_p_data[0]) + { + // Always copy old value to new pointer when data type matches + if(p_signal->data_type == data_type) + { + dc_set_signal_val(p_data, data_type, p_signal->vec_p_data[0]); + } + + { + std::lock_guard lock(g_datacenter.signal_ao.mtx); + dc_delete_signal_data(p_signal->vec_p_data[0], data_type); + p_signal->vec_p_data[0] = p_data; + p_signal->change_cb_list.push_back({module_id, cb}); + } + return 0; + } + + dc_set_param_cfg_change(true); + + stru_signal signal; + signal.hash = hash; + signal.saddr.assign(saddr); + signal.desc.assign(desc); + signal.data_type = data_type; + dc_signal_apply_metadata(signal); + signal.ctrl_type = ctrl_type; + + dc_signal_add_to_map(signal, g_datacenter.signal_ao); + + p_signal = dc_find_signal(saddr, g_datacenter.signal_ao); + if(p_signal != nullptr ) + { + p_signal->vec_p_data.push_back(p_data); + + if(cb) + { + p_signal->change_cb_list.push_back({module_id, cb}); + } + + return 0; + } + + return -1; +} + +int dc_signal_ao_link_with_callback(const std::string &saddr, void **p_data, signal_change_cb cb, const std::string &module_id) +{ + if(p_data == nullptr) + { + MY_LOG_E("p_data is nullptr"); + return -1; + } + + XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao); + if(p_signal != nullptr) + { + if(cb) + { + p_signal->change_cb_list.push_back({module_id, cb}); + } + + (*p_data) = p_signal->vec_p_data.empty() ? nullptr : p_signal->vec_p_data[0]; + return (*p_data) != nullptr ? 0 : -1; + } + + return -1; +} + +int dc_signal_ao_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, void *p_data, const std::string &module_id) +{ + if(p_data == nullptr) + { + MY_LOG_E("p_data is nullptr"); + return -1; + } + + XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao); + if(p_signal != nullptr) + { + if(0 == dc_check_ctrl_valid(p_signal, step, ctrl, p_data)) + { + if(0 != dc_check_val_valid(p_signal, 0, p_data)) + { + LOG_E("invalid value for saddr %s", saddr.c_str()); + + return -1; + } + + if(step == SIGNAL_CTRL_STEP::SELECT) + { + dc_set_signal_val(ctrl.p_data, ctrl.data_type, p_data); + ctrl.step = step; + } + else if(step == SIGNAL_CTRL_STEP::DIRECT) + { + dc_set_signal_val(p_signal->vec_p_data[0], ctrl.data_type, p_data); + ctrl.step = SIGNAL_CTRL_STEP::READY; + } + else if(step == SIGNAL_CTRL_STEP::CANCEL) + { + ctrl.step = SIGNAL_CTRL_STEP::READY; + } + else + { + LOG_E("invalid step %d", step); + return -1; + } + + for(auto &entry : p_signal->change_cb_list) + { + if(entry.second) + { + // 回路阻断:修改本信号的模块不回调自身 + if (entry.first == module_id) continue; + entry.second(saddr, step, ctrl.data_type, 0, p_data); + } + } + + dc_set_param_cfg_change(true); + + return 0; + } + else + { + LOG_E("saddr %s ctrl invalid", saddr.c_str()); + ctrl.step = SIGNAL_CTRL_STEP::READY; + return -1; + } + } + + LOG_E("saddr %s not found", saddr.c_str()); + + return -1; +} + +int dc_signal_ao_set_val_without_check(const std::string &saddr, uint8_t data_type, void *p_data, const std::string &module_id) +{ + if(p_data == nullptr) + { + MY_LOG_E("p_data is nullptr"); + return -1; + } + + XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao); + if(p_signal != nullptr && !p_signal->vec_p_data.empty() && p_signal->data_type == data_type && p_signal->vec_p_data[0]) + { + if(p_signal->data_type != data_type) + { + LOG_E("saddr %s data type %s(%d) not match ctrl data type %s(%d)", + saddr.c_str(), dc_get_data_type_str_by_id(p_signal->data_type), p_signal->data_type, dc_get_data_type_str_by_id(data_type), data_type); + return -1; + } + + if(0 != dc_check_val_valid(p_signal, 0, p_data)) + { + return -1; + } + + dc_set_signal_val(p_signal->vec_p_data[0], data_type, p_data); + dc_set_param_cfg_change(true); + + for(auto &entry : p_signal->change_cb_list) + { + if(entry.second) + { + if (entry.first == module_id) continue; + entry.second(saddr, SIGNAL_CTRL_STEP::DIRECT, data_type, 0, p_data); + } + } + + return 0; + } + else + { + // LOG_E("saddr %s, p_signal %p, vec_size %d, data_type %d,%d, p_data %p", saddr.c_str(), p_signal, p_signal->vec_p_data.size(), p_signal->data_type, data_type, p_signal->vec_p_data[0]); + } + + LOG_E("saddr %s not found in ao table", saddr.c_str()); + return -1; +} + +int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t data_type, uint8_t ctrl_type, void **p_data, int data_num, signal_change_cb cb, const std::string &module_id) +{ + // 先从参数表里解析,调用参数注册 + // 程序注册时,从参数表里去查找,同一个信息,使用参数表中的保存的数据值,在线程初始化时,通知所有链接此信号的信号 + // 注册时不在参数表中的,新增到动态表里,并保存到参数表里,使用缺省值 + + if(0 == data_num) + { + MY_LOG_E("data_num is 0"); + return -1; + } + + for(int i = 0; i < data_num; i++) + { + if(p_data[i] == nullptr) + { + LOG_E("p_data[%d] is nullptr", i); + return -1; + } + } + + XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param); + if(p_signal != nullptr) + { + // Always copy old values to new pointers when data type matches + if(p_signal->data_type == data_type) + { + size_t copy_num = (data_num < p_signal->vec_p_data.size()) ? data_num : p_signal->vec_p_data.size(); + for(size_t i = 0; i < copy_num; i++) + { + dc_set_signal_val(p_data[i], data_type, p_signal->vec_p_data[i]); + } + } + + // dc_set_signal_val(p_data, data_type, p_signal->p_data); + dc_set_param_cfg_change(true); + { + std::lock_guard lock(g_datacenter.signal_param.mtx); + + for(size_t i = 0; i < p_signal->vec_p_data.size(); i++) + { + dc_delete_signal_data(p_signal->vec_p_data[i], data_type); + } + + p_signal->vec_p_data.clear(); + + for(size_t i = 0; i < data_num; i++) + { + p_signal->vec_p_data.push_back(p_data[i]); + } + + p_signal->change_cb_list.push_back({module_id, cb}); + } + return 0; + } + + dc_set_param_cfg_change(true); + + stru_signal signal; + signal.hash = hash; + signal.saddr.assign(saddr); + signal.desc.assign(desc); + signal.data_type = data_type; + dc_signal_apply_metadata(signal); + signal.ctrl_type = ctrl_type; + + dc_signal_add_to_map(signal, g_datacenter.signal_param); + + p_signal = dc_find_signal(saddr, g_datacenter.signal_param); + if(p_signal != nullptr ) + { + for(size_t i = 0; i < data_num; i++) + { + p_signal->vec_p_data.push_back(p_data[i]); + + } + + if(cb) + { + p_signal->change_cb_list.push_back({module_id, cb}); + } + return 0; + } + + return -1; +} + +int dc_signal_param_link_with_callback(const std::string &saddr, void **p_data, int data_num, signal_change_cb cb, const std::string &module_id) +{ + XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param); + if(p_signal != nullptr) + { + if(cb) + { + p_signal->change_cb_list.push_back({module_id, cb}); + } + + for(size_t i = 0; i < p_signal->vec_p_data.size() && i < data_num; i++) + { + p_data[i] = p_signal->vec_p_data[i]; + } + return 0; + } + + return -1; +} + + +int dc_signal_param_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, uint8_t setting_zone, void *p_data, const std::string &module_id) +{ + if(p_data == nullptr) + { + MY_LOG_E("p_data is nullptr"); + return -1; + } + + XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param); + if(p_signal != nullptr) + { + if(0 == dc_check_ctrl_valid(p_signal, step, ctrl, p_data)) + { + if(0 != dc_check_val_valid(p_signal, setting_zone, p_data)) + { + LOG_E("invalid value for saddr %s", saddr.c_str()); + return -1; + } + + if(step == SIGNAL_CTRL_STEP::SELECT) + { + dc_set_signal_val(ctrl.p_data, ctrl.data_type, p_data); + ctrl.step = SIGNAL_CTRL_STEP::SELECT; + } + else if(step == SIGNAL_CTRL_STEP::DIRECT) + { + dc_set_signal_val(p_signal->vec_p_data[setting_zone], ctrl.data_type, p_data); + ctrl.step = SIGNAL_CTRL_STEP::READY; + } + else if(step == SIGNAL_CTRL_STEP::CANCEL) + { + ctrl.step = SIGNAL_CTRL_STEP::READY; + } + else + { + LOG_E("invalid ctrl step %d", step); + return -1; + } + + for(auto &entry : p_signal->change_cb_list) + { + if(entry.second != nullptr) + { + // 回路阻断:修改本信号的模块不回调自身 + if (entry.first == module_id) continue; + entry.second(saddr, step, ctrl.data_type, setting_zone, p_data); + } + } + + dc_set_param_cfg_change(true); + + return 0; + } + else + { + LOG_E("saddr %s ctrl invalid", saddr.c_str()); + ctrl.step = SIGNAL_CTRL_STEP::READY; + return -1; + } + } + + LOG_E("saddr %s not found in param table", saddr.c_str()); + + return -1; +} + +int dc_signal_param_set_val_without_check(const std::string &saddr, uint8_t data_type, uint8_t setting_zone, void *p_data, const std::string &module_id) +{ + if(p_data == nullptr) + { + MY_LOG_E("p_data is nullptr"); + return -1; + } + + XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param); + + if(p_signal != nullptr && setting_zone < p_signal->vec_p_data.size()) + { + if(p_signal->data_type != data_type) + { + LOG_E("saddr %s data type %s(%d) not match ctrl data type %s(%d)", + saddr.c_str(), dc_get_data_type_str_by_id(p_signal->data_type), p_signal->data_type, dc_get_data_type_str_by_id(data_type), data_type); + return -1; + } + + if(0 != dc_check_val_valid(p_signal, setting_zone, p_data)) + { + return -1; + } + dc_set_signal_val(p_signal->vec_p_data[setting_zone], data_type, p_data); + dc_set_param_cfg_change(true); + + for(auto &entry : p_signal->change_cb_list) + { + if(entry.second != nullptr) + { + if (entry.first == module_id) continue; + entry.second(saddr, SIGNAL_CTRL_STEP::DIRECT, data_type, setting_zone, p_data); + } + } + + return 0; + } + + LOG_E("saddr %s not found in param table", saddr.c_str()); + return -1; +} + +int dc_signal_yk(const std::string &saddr, const std::string &desc, uint8_t data_type, uint8_t ctrl_type, void *p_data, signal_change_cb cb, const std::string &module_id) +{ + if(p_data == nullptr) + { + MY_LOG_E("p_data is nullptr"); + return -1; + } + + stru_signal signal; + + signal.hash = XXH3_128bits(saddr.c_str(), saddr.length()); + signal.saddr.assign(saddr); + signal.desc.assign(desc); + signal.data_type = data_type; + signal.vec_p_data.push_back(p_data); + + dc_signal_add_to_map(signal, g_datacenter.signal_yk); + + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_yk); + if(p_signal != nullptr) + { + if(cb) + { + p_signal->change_cb_list.push_back({module_id, cb}); + } + + p_signal->ctrl_type = ctrl_type; + + return 0; + } + + return -1; +} + +int dc_signal_yk_link_with_callback(const std::string &saddr, void **p_data, signal_change_cb cb, const std::string &module_id) +{ + if(p_data == nullptr) + { + MY_LOG_E("p_data is nullptr"); + return -1; + } + + XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_yk); + if(p_signal != nullptr) + { + if(cb) + { + p_signal->change_cb_list.push_back({module_id, cb}); + } + (*p_data) = p_signal->vec_p_data.empty() ? nullptr : p_signal->vec_p_data[0]; + return (*p_data) != nullptr ? 0 : -1; + } + + return -1; +} + +int dc_signal_yk_set_status(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, void *p_data, const std::string &module_id) +{ + if(p_data == nullptr) + { + MY_LOG_E("p_data is nullptr"); + return -1; + } + + XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_yk); + if(p_signal != nullptr) + { + if(0 == dc_check_ctrl_valid(p_signal, step, ctrl, p_data)) + { + if(0 != dc_check_yk_val_valid(p_signal, p_data)) + { + LOG_E("YK val check failed, saddr=%s", saddr.c_str()); + return -1; + } + + if(step == SIGNAL_CTRL_STEP::SELECT) + { + dc_set_signal_val(ctrl.p_data, ctrl.data_type, p_data); + ctrl.step = SIGNAL_CTRL_STEP::SELECT; + } + else if(step == SIGNAL_CTRL_STEP::DIRECT) + { + dc_set_signal_val(p_signal->vec_p_data[0], ctrl.data_type, p_data); + ctrl.step = SIGNAL_CTRL_STEP::READY; + } + else if(step == SIGNAL_CTRL_STEP::CANCEL) + { + ctrl.step = SIGNAL_CTRL_STEP::READY; + } + else + { + LOG_E("invalid ctrl step %d", step); + return -1; + } + + for(auto &entry : p_signal->change_cb_list) + { + if(entry.second != nullptr) + { + // 回路阻断:修改本信号的模块不回调自身 + if (entry.first == module_id) continue; + entry.second(saddr, step, ctrl.data_type, 0, p_data); + } + } + + return 0; + } + else + { + LOG_E("saddr %s ctrl invalid", saddr.c_str()); + ctrl.step = SIGNAL_CTRL_STEP::READY; + return -1; + } + } + + LOG_E("saddr %s not found in yk table", saddr.c_str()); + + return -1; +} + diff --git a/src/public/libdatacenter/src/dc_signal_ctrl.cpp b/src/public/libdatacenter/src/dc_signal_ctrl.cpp new file mode 100644 index 0000000..94b3835 --- /dev/null +++ b/src/public/libdatacenter/src/dc_signal_ctrl.cpp @@ -0,0 +1,423 @@ +#include "dc_signal_internal.h" +int dc_check_ctrl_val_valid(const stru_signal_ctrl &ctrl, const void *p_data) +{ + if(ctrl.data_type == DATA_TYPE_B || ctrl.data_type == DATA_TYPE_U8) + { + if(*(uint8_t *)p_data != *(uint8_t *)ctrl.p_data) + { + LOG_E("direct ctrl value %d not match selected value %d", *(uint8_t*)p_data, *(uint8_t*)ctrl.p_data); + return -1; + } + } + else if(ctrl.data_type == DATA_TYPE_S8) + { + if(*(int8_t *)p_data != *(int8_t *)ctrl.p_data) + { + LOG_E("direct ctrl value %d not match selected value %d", *(int8_t*)p_data, *(int8_t*)ctrl.p_data); + return -1; + } + } + else if(ctrl.data_type == DATA_TYPE_S16) + { + if(*(int16_t *)p_data != *(int16_t *)ctrl.p_data) + { + LOG_E("direct ctrl value %d not match selected value %d", *(int16_t*)p_data, *(int16_t*)ctrl.p_data); + return -1; + } + } + else if(ctrl.data_type == DATA_TYPE_U16) + { + if(*(uint16_t *)p_data != *(uint16_t *)ctrl.p_data) + { + LOG_E("direct ctrl value %d not match selected value %d", *(uint16_t*)p_data, *(uint16_t*)ctrl.p_data); + return -1; + } + } + else if(ctrl.data_type == DATA_TYPE_S32) + { + if(*(int32_t *)p_data != *(int32_t *)ctrl.p_data) + { + LOG_E("direct ctrl value %d not match selected value %d", *(int32_t*)p_data, *(int32_t*)ctrl.p_data); + return -1; + } + } + else if(ctrl.data_type == DATA_TYPE_U32) + { + if(*(uint32_t *)p_data != *(uint32_t *)ctrl.p_data) + { + LOG_E("direct ctrl value %d not match selected value %d", *(uint32_t*)p_data, *(uint32_t*)ctrl.p_data); + return -1; + } + } + else if(ctrl.data_type == DATA_TYPE_L64) + { + if(*(int64_t *)p_data != *(int64_t *)ctrl.p_data) + { + LOG_E("direct ctrl value %lld not match selected value %lld", *(int64_t*)p_data, *(int64_t*)ctrl.p_data); + return -1; + } + } + else if(ctrl.data_type == DATA_TYPE_UL64) + { + if(*(uint64_t *)p_data != *(uint64_t *)ctrl.p_data) + { + LOG_E("direct ctrl value %lld not match selected value %lld", *(uint64_t*)p_data, *(uint64_t*)ctrl.p_data); + return -1; + } + } + else if(ctrl.data_type == DATA_TYPE_F32) + { + if(*(float*)p_data != *(float*)ctrl.p_data) + { + LOG_E("direct ctrl value %f not match selected value %f", *(float*)p_data, *(float*)ctrl.p_data); + return -1; + } + } + else if(ctrl.data_type == DATA_TYPE_D64) + { + if(*(double*)p_data != *(double*)ctrl.p_data) + { + LOG_E("direct ctrl value %lf not match selected value %lf", *(double*)p_data, *(double*)ctrl.p_data); + return -1; + } + } + else if(ctrl.data_type == DATA_TYPE_IP) + { + if(0 != memcmp((char *)ctrl.p_data, (char *)p_data, 4)) + { + LOG_E("direct ctrl value %s not match selected value %s", + dc_get_signal_val(ctrl.p_data, DATA_TYPE_IP).c_str(), dc_get_signal_val((char *)p_data, DATA_TYPE_IP).c_str()); + return -1; + } + } + else if(ctrl.data_type == DATA_TYPE_MAC) + { + if(0 != memcmp((char *)ctrl.p_data, (char *)p_data, 6)) + { + LOG_E("direct ctrl value %s not match selected value %s", + dc_get_signal_val(ctrl.p_data, DATA_TYPE_MAC).c_str(), dc_get_signal_val((char *)p_data, DATA_TYPE_MAC).c_str()); + return -1; + } + } + else if(ctrl.data_type == DATA_TYPE_C1) + { + if(*(char*)p_data != *(char*)ctrl.p_data) + { + LOG_E("direct ctrl value %c not match selected value %c", *(char*)p_data, *(char*)ctrl.p_data); + return -1; + } + } + else if(ctrl.data_type == DATA_TYPE_C8 || ctrl.data_type == DATA_TYPE_C32 || ctrl.data_type == DATA_TYPE_C64 || ctrl.data_type == DATA_TYPE_C128 || ctrl.data_type == DATA_TYPE_STR) + { + if(0 != strcmp((char *)ctrl.p_data, (char *)p_data)) + { + LOG_E("direct ctrl value %s not match selected value %s", (char *)ctrl.p_data, (char *)p_data); + return -1; + } + } + else + { + LOG_E("invalid ctrl data_type %d", ctrl.data_type); + return -1; + } + + return 0; +} + +int dc_check_ctrl_valid(const stru_signal *p_signal, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, const void *p_data) +{ + // LOG_I("dc_check_ctrl_valid %s, step %d, data_type %d, p_data %d", p_signal->saddr.c_str(), step, data_type, *(uint8_t *)p_data); + + if(p_signal->data_type != ctrl.data_type) + { + LOG_E("%s data_type %d not match ctrl data_type %d", p_signal->saddr.c_str(), p_signal->data_type, ctrl.data_type); + return -1; + } + + if(ctrl.type == SIGNAL_CTRL_TYPE::DIRECT_NORMAL) + { + if(step == SIGNAL_CTRL_STEP::DIRECT) + { + return 0; + } + else + { + LOG_E("%s ctrl_type %d, invalid ctrl step %d", p_signal->saddr.c_str(), ctrl.type, ctrl.step); + return -1; + } + } + else if(ctrl.type == SIGNAL_CTRL_TYPE::SBO_NORMAL) + { + if(ctrl.step == SIGNAL_CTRL_STEP::READY) + { + if(step == SIGNAL_CTRL_STEP::SELECT) + { + return 0; + } + else + { + LOG_E("%s ctrl_type %d, invalid ctrl step %d", p_signal->saddr.c_str(), ctrl.type, ctrl.step); + return -1; + } + } + else if(ctrl.step == SIGNAL_CTRL_STEP::SELECT) + { + if(step == SIGNAL_CTRL_STEP::DIRECT) + { + if(0 == dc_check_ctrl_val_valid(ctrl, p_data)) + { + return 0; + } + else + { + LOG_E("%s ctrl_type %d, direct value not match selected value", p_signal->saddr.c_str(), ctrl.type); + return -1; + } + } + else if(step == SIGNAL_CTRL_STEP::CANCEL) + { + return 0; + } + else + { + LOG_E("%s ctrl_type %d, invalid ctrl step %d", p_signal->saddr.c_str(), ctrl.type, ctrl.step); + return -1; + } + } + } + + LOG_E("invalid ctrl type %d", ctrl.type); + return -1; +} + + + +int dc_check_val_valid(const stru_signal *p_signal, uint8_t setting_zone, const void *p_data) +{ + stru_signal_param param = p_signal->param; + + if(setting_zone >= p_signal->vec_p_data.size()) + { + LOG_E("%s setting_zone %d out of range, vec_p_data size %d", p_signal->saddr.c_str(), setting_zone, (int)p_signal->vec_p_data.size()); + return -1; + } + + void *current_p_data = p_signal->vec_p_data[setting_zone]; + + if(p_signal->data_type == DATA_TYPE_B) + { + if(*(uint8_t *)current_p_data == *(uint8_t *)p_data) + { + LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint8_t*)current_p_data); + return -1; + } + + uint8_t b = *(uint8_t*)p_data; + if(b != 0 && b != 1) + { + LOG_E("invalid bool value %d", b); + return -1; + } + } + else if(p_signal->data_type == DATA_TYPE_S8) + { + if(*(int8_t*)current_p_data == *(int8_t*)p_data) + { + LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(int8_t*)current_p_data); + return -1; + } + + int8_t s8 = *(int8_t*)p_data; + if(s8 < (int8_t)param.min || s8 > (int8_t)param.max) + { + LOG_E("invalid int8_t value %d, range [%f, %f]", s8, param.min, param.max); + return -1; + } + } + else if(p_signal->data_type == DATA_TYPE_U8) + { + if(*(uint8_t*)current_p_data == *(uint8_t*)p_data) + { + LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint8_t*)current_p_data); + return -1; + } + + uint8_t u8 = *(uint8_t*)p_data; + if(u8 < param.min || u8 > param.max) + { + LOG_E("invalid uint8_t value %d, range [%f, %f]", u8, param.min, param.max); + return -1; + } + } + else if(p_signal->data_type == DATA_TYPE_S16) + { + if(*(int16_t*)current_p_data == *(int16_t*)p_data) + { + LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(int16_t*)current_p_data); + return -1; + } + + int16_t s16 = *(int16_t*)p_data; + if(s16 < (int16_t)param.min || s16 > (int16_t)param.max) + { + LOG_E("invalid int16_t value %d, range [%d, %d]", s16, param.min, param.max); + return -1; + } + } + else if(p_signal->data_type == DATA_TYPE_U16) + { + if(*(uint16_t*)current_p_data == *(uint16_t*)p_data) + { + LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint16_t*)current_p_data); + return -1; + } + + uint16_t u16 = *(uint16_t*)p_data; + if(u16 < param.min || u16 > param.max) + { + LOG_E("invalid uint16_t value %d, range [%f, %f]", u16, param.min, param.max); + return -1; + } + } + else if(p_signal->data_type == DATA_TYPE_S32) + { + if(*(int32_t*)current_p_data == *(int32_t*)p_data) + { + LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(int32_t*)current_p_data); + return -1; + } + + int32_t s32 = *(int32_t*)p_data; + if(s32 < (int32_t)param.min || s32 > (int32_t)param.max) + { + LOG_E("invalid int32_t value %d, range [%f, %f]", s32, param.min, param.max); + return -1; + } + } + else if(p_signal->data_type == DATA_TYPE_U32) + { + if(*(uint32_t*)current_p_data == *(uint32_t*)p_data) + { + LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint32_t*)current_p_data); + return -1; + } + + uint32_t u32 = *(uint32_t*)p_data; + if(u32 < param.min || u32 > param.max) + { + LOG_E("invalid uint32_t value %d, range [%f, %f]", u32, param.min, param.max); + return -1; + } + } + else if(p_signal->data_type == DATA_TYPE_L64) + { + if(*(int64_t*)current_p_data == *(int64_t*)p_data) + { + LOG_E("%s value %lld not changed", p_signal->saddr.c_str(), *(int64_t*)current_p_data); + return -1; + } + + int64_t l64 = *(int64_t*)p_data; + if(l64 < (int64_t)param.min || l64 > (int64_t)param.max) + { + LOG_E("invalid int64_t value %lld, range [%f, %f]", l64, param.min, param.max); + return -1; + } + } + else if(p_signal->data_type == DATA_TYPE_UL64) + { + if(*(uint64_t*)current_p_data == *(uint64_t*)p_data) + { + LOG_E("%s value %llu not changed", p_signal->saddr.c_str(), *(uint64_t*)current_p_data); + return -1; + } + + uint64_t ul64 = *(uint64_t*)p_data; + if(ul64 < param.min || ul64 > param.max) + { + LOG_E("invalid uint64_t value %llu, range [%f, %f]", ul64, param.min, param.max); + return -1; + } + } + else if(p_signal->data_type == DATA_TYPE_F32) + { + if(*(float*)current_p_data == *(float*)p_data) + { + LOG_E("%s value %f not changed", p_signal->saddr.c_str(), *(float*)current_p_data); + return -1; + } + + float f32 = *(float*)p_data; + if(f32 < (float)param.min || f32 > (float)param.max) + { + LOG_E("invalid float value %f, range [%f, %f]", f32, param.min, param.max); + return -1; + } + } + else if(p_signal->data_type == DATA_TYPE_D64) + { + if(*(double*)current_p_data == *(double*)p_data) + { + LOG_E("%s value %f not changed", p_signal->saddr.c_str(), *(double*)current_p_data); + return -1; + } + + double d64 = *(double*)p_data; + if(d64 < (double)param.min || d64 > (double)param.max) + { + LOG_E("invalid double value %f, range [%f, %f]", d64, param.min, param.max); + return -1; + } + } + else if(p_signal->data_type == DATA_TYPE_IP || + p_signal->data_type == DATA_TYPE_MAC || + p_signal->data_type == DATA_TYPE_C8 || + p_signal->data_type == DATA_TYPE_C32 || + p_signal->data_type == DATA_TYPE_C64 || + p_signal->data_type == DATA_TYPE_C128 || + p_signal->data_type == DATA_TYPE_STR) + { + if(0 == strcmp((char *)current_p_data, (char *)p_data)) + { + LOG_E("%s value %s not changed", p_signal->saddr.c_str(), (char*)current_p_data); + return -1; + } + } + else if(p_signal->data_type == DATA_TYPE_C1) + { + if(*(char*)current_p_data == *(char*)p_data) + { + LOG_E("%s value %c not changed", p_signal->saddr.c_str(), *(char*)current_p_data); + return -1; + } + } + else + { + LOG_E("data_type is not valid: %d", p_signal->data_type); + return -1; + } + + return 0; +} + +int dc_check_yk_val_valid(stru_signal *p_signal, void *p_data) +{ + if(p_signal->data_type == DATA_TYPE_B || p_signal->data_type == DATA_TYPE_U8) + { + uint8_t u8 = *(uint8_t*)p_data; + if(u8 != 0 && u8 != 1) + { + LOG_E("invalid uint8_t value %d, range [0, 1]", u8); + return -1; + } + } + else + { + LOG_E("data_type is not valid: %d", p_signal->data_type); + return -1; + } + + return 0; +} + + diff --git a/src/public/libdatacenter/src/dc_signal_find.cpp b/src/public/libdatacenter/src/dc_signal_find.cpp new file mode 100644 index 0000000..5779edf --- /dev/null +++ b/src/public/libdatacenter/src/dc_signal_find.cpp @@ -0,0 +1,25 @@ +#include "dc_signal_internal.h" +stru_signal* dc_find_signal(const std::string &saddr, stru_signal_map &dc_signal_map) +{ + XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); + std::lock_guard lock(dc_signal_map.mtx); + + auto range = dc_signal_map.map_signals.equal_range(hash); + for (auto it = range.first; it != range.second; ++it) { + if (it->second.saddr == saddr) { + return &it->second; + } + } + return nullptr; +} + + +stru_signal* dc_find_out_signal(const std::string &saddr) +{ + return dc_find_signal(saddr, g_datacenter.signal_out); +} + +stru_signal* dc_find_in_signal(const std::string &saddr) +{ + return dc_find_signal(saddr, g_datacenter.signal_in); +} diff --git a/src/public/libdatacenter/src/dc_signal_internal.h b/src/public/libdatacenter/src/dc_signal_internal.h new file mode 100644 index 0000000..0173c68 --- /dev/null +++ b/src/public/libdatacenter/src/dc_signal_internal.h @@ -0,0 +1,93 @@ +/** + * @file dc_signal_internal.h + * @brief dc_signal 模块内部共享声明 + */ +#ifndef DC_SIGNAL_INTERNAL_H +#define DC_SIGNAL_INTERNAL_H + +#include "dc_signal.h" +#include "dc_param.h" +#include "myDatacenter.h" +#include "myLog.h" +#include "xxhash.h" + +#include +#include +#include +#include +#include +#include + +/* ================================================================ + * 哈希函数对象 + * ================================================================ */ +struct XXH128Hash { + size_t operator()(const XXH128_hash_t& h) const noexcept; +}; + +struct XXH128Equal { + bool operator()(const XXH128_hash_t& a, const XXH128_hash_t& b) const noexcept; +}; + +typedef std::unordered_multimap hash_signal_map; + +typedef struct { + std::mutex mtx; + uint32_t signal_id; + hash_signal_map map_signals; + std::vector id_index; +} stru_signal_map; + +typedef struct { + stru_signal_map signal_out; + stru_signal_map signal_in; + stru_signal_map signal_yk; + stru_signal_map signal_ao; + stru_signal_map signal_param; +} stru_datacenter; + +/* ================================================================ + * 全局变量 + * ================================================================ */ +extern stru_datacenter g_datacenter; +extern bool g_param_cfg_change; +extern std::mutex g_param_cfg_change_mutex; +extern std::vector g_dirty_out_signals; +extern std::mutex g_dirty_out_mutex; + +/* ================================================================ + * 跨文件共享函数 + * ================================================================ */ +void dc_mark_signal_dirty(stru_signal *p_signal); +int dc_data_compare(uint8_t data_type, void *p_data, void *p_data2); +void dc_signal_apply_metadata(stru_signal &signal); +int dc_check_ctrl_val_valid(const stru_signal_ctrl &ctrl, const void *p_data); +int dc_check_ctrl_valid(const stru_signal *p_signal, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, const void *p_data); +int dc_check_val_valid(const stru_signal *p_signal, uint8_t setting_zone, const void *p_data); +int dc_check_yk_val_valid(stru_signal *p_signal, void *p_data); +int dc_signal_add_to_map(stru_signal &signal, stru_signal_map &dc_signal_map); +stru_signal* dc_find_signal(const std::string &saddr, stru_signal_map &dc_signal_map); +stru_signal* dc_find_out_signal(const std::string &saddr); +stru_signal* dc_find_in_signal(const std::string &saddr); +int dc_set_signal_val(void *p_data, uint8_t data_type, void *set_data); +stru_signal* dc_find_signal_by_id(uint32_t id, stru_signal_map &dc_signal_map); + +/* data_type 工具函数(util 提供,多文件使用) */ +std::string dc_get_signal_val(void *p_data, uint8_t data_type); +std::string dc_get_data_type_str_by_id(uint8_t data_type); +uint8_t dc_get_data_type_id_by_str(const std::string &data_type_str); +uint8_t dc_get_data_type_len(uint8_t data_type); +void dc_set_signal_val_from_str(void *p_data, uint8_t data_type, const std::string &str); +void *dc_create_data_ptr_by_type(uint8_t data_type); +void dc_delete_signal_data(void *p_data, uint8_t data_type); + +/* 对外接口 */ +int dc_get_out_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, void **p_data); +int dc_get_in_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, void **p_data); +int dc_get_ao_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param *p_param, uint8_t &ctrl_type, void **p_data); +int dc_get_param_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param *p_param, uint8_t &ctrl_type, std::vector *p_vec_p_data); +int dc_get_yk_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, uint8_t &ctrl_type, void **p_data); +int dc_set_out_signal_val(const std::string &saddr, void *set_data, const std::string &module_id); +uint32_t dc_get_signal_count(const char *type); + +#endif // DC_SIGNAL_INTERNAL_H diff --git a/src/public/libdatacenter/src/dc_signal_query.cpp b/src/public/libdatacenter/src/dc_signal_query.cpp new file mode 100644 index 0000000..ce8cc29 --- /dev/null +++ b/src/public/libdatacenter/src/dc_signal_query.cpp @@ -0,0 +1,206 @@ +#include "dc_signal_internal.h" +bool dc_get_param_cfg_change() +{ + bool change = false; + std::lock_guard lock(g_param_cfg_change_mutex); + change = g_param_cfg_change; + + return change; +} + +void dc_set_param_cfg_change(bool change) +{ + std::lock_guard lock(g_param_cfg_change_mutex); + g_param_cfg_change = change; +} + + + + +int dc_get_out_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, void **p_data) +{ + stru_signal *p_signal = dc_find_out_signal(saddr); + if(p_signal == nullptr) + { + MY_LOG_E("saddr %s not found", saddr.c_str()); + return -1; + } + + desc = p_signal->desc; + data_type = p_signal->data_type; + + if(p_signal->vec_p_data.empty()) + { + MY_LOG_E("saddr %s vec_p_data is empty", saddr.c_str()); + return -1; + } + + if(nullptr == p_signal->vec_p_data[0]) + { + MY_LOG_E("saddr %s vec_p_data[0] is nullptr", saddr.c_str()); + return -1; + } + + if(p_data != nullptr) + { + (*p_data) = p_signal->vec_p_data[0]; + } + + return 0; +} + +int dc_get_in_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, void **p_data) +{ + stru_signal *p_signal = dc_find_in_signal(saddr); + if(p_signal == nullptr) + { + MY_LOG_E("saddr %s not found", saddr.c_str()); + return -1; + } + + desc = p_signal->desc; + data_type = p_signal->data_type; + + if(!p_signal->vec_p_data.empty() && nullptr != p_signal->vec_p_data[0]) + { + if(p_data != nullptr) + { + (*p_data) = p_signal->vec_p_data[0]; + } + + return 0; + } + + MY_LOG_E("saddr %s vec_p_data is empty or vec_p_data[0] is nullptr", saddr.c_str()); + return -1; +} + +int dc_get_ao_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param *p_param, uint8_t &ctrl_type, void **p_data) +{ + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao); + if(p_signal == nullptr) + { + MY_LOG_E("saddr %s not found", saddr.c_str()); + return -1; + } + + desc = p_signal->desc; + data_type = p_signal->data_type; + if(p_param != nullptr) + { + p_param->min = p_signal->param.min; + p_param->max = p_signal->param.max; + p_param->step = p_signal->param.step; + p_param->unit = p_signal->param.unit; + } + ctrl_type = p_signal->ctrl_type; + + if(!p_signal->vec_p_data.empty() && nullptr != p_signal->vec_p_data[0]) + { + if(p_data != nullptr) + { + (*p_data) = p_signal->vec_p_data[0]; + } + } + else + { + MY_LOG_E("saddr %s vec_p_data is empty or vec_p_data[0] is nullptr", saddr.c_str()); + return -1; + } + + + return 0; +} + +int dc_get_param_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param *p_param, uint8_t &ctrl_type, std::vector *p_vec_p_data) +{ + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param); + if(p_signal == nullptr) + { + MY_LOG_E("saddr %s not found", saddr.c_str()); + return -1; + } + desc = p_signal->desc; + data_type = p_signal->data_type; + if(p_param != nullptr) + { + p_param->min = p_signal->param.min; + p_param->max = p_signal->param.max; + p_param->step = p_signal->param.step; + p_param->unit = p_signal->param.unit; + } + ctrl_type = p_signal->ctrl_type; + + for(size_t i = 0; i < p_signal->vec_p_data.size(); i++) + { + if(nullptr == p_signal->vec_p_data[i]) + { + MY_LOG_E("saddr %s vec_p_data[%ld] is nullptr", saddr.c_str(), i); + return -1; + } + if(p_vec_p_data != nullptr) + { + p_vec_p_data->push_back(p_signal->vec_p_data[i]); + } + } + + + + return 0; +} + +int dc_get_yk_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, uint8_t &ctrl_type, void **p_data) +{ + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_yk); + if(p_signal == nullptr) + { + MY_LOG_E("saddr %s not found", saddr.c_str()); + return -1; + } + desc = p_signal->desc; + data_type = p_signal->data_type; + ctrl_type = p_signal->ctrl_type; + if(p_data != nullptr) + { + *p_data = p_signal->vec_p_data[0]; + } + + return 0; +} + + +void dc_signal_out_change_check() +{ + std::vector dirty; + { + std::lock_guard lock(g_dirty_out_mutex); + dirty.swap(g_dirty_out_signals); + } + + if (dirty.empty()) return; + + // 去重:同一信号可能多次写入 + std::sort(dirty.begin(), dirty.end()); + auto last = std::unique(dirty.begin(), dirty.end()); + + for (auto it = dirty.begin(); it != last; ++it) { + stru_signal *p_signal = *it; + if (!p_signal->out_change_cb_list.empty() && + nullptr != p_signal->vec_p_data[0] && + nullptr != p_signal->p_last_data) + { + if (0 != dc_data_compare(p_signal->data_type, + p_signal->vec_p_data[0], p_signal->p_last_data)) + { + for (auto &entry : p_signal->out_change_cb_list) { + // 回路阻断:修改本信号的模块不回调自身 + if (entry.first == p_signal->last_caller_module) continue; + entry.second(p_signal->saddr, p_signal->data_type, + p_signal->vec_p_data[0], p_signal->p_last_data); + } + dc_set_signal_val(p_signal->p_last_data, + p_signal->data_type, p_signal->vec_p_data[0]); + } + } + } +} diff --git a/src/public/libdatacenter/src/dc_signal_show.cpp b/src/public/libdatacenter/src/dc_signal_show.cpp new file mode 100644 index 0000000..520db6f --- /dev/null +++ b/src/public/libdatacenter/src/dc_signal_show.cpp @@ -0,0 +1,232 @@ +#include "dc_signal_internal.h" +#include +#include "myCmd.h" +LOCAL void dc_show_signals(stru_signal_map &dc_signal_map) +{ + using namespace std; + + hash_signal_map &signal_map = dc_signal_map.map_signals; + + // 定义列宽(单位:终端视觉列数,中文占2列,ASCII占1列) + const int COL_ID = 8; + const int COL_SADDR = 36; + const int COL_DESC = 48; + const int COL_TYPE = 10; + const int COL_VAL = 24; + const int COL_LINK = 48; + + // 按终端视觉宽度左对齐辅助函数 + auto visual_width = [](const std::string &s) -> int { + int w = 0; + for (size_t i = 0; i < s.size();) { + unsigned char c = s[i]; + if (c < 0x80) { w += 1; i += 1; } + else if (c < 0xC0) { i += 1; } // 连续字节不计宽 + else if (c < 0xE0) { w += 2; i += 2; } // 2字节字符 + else if (c < 0xF0) { w += 2; i += 3; } // CJK 3字节 + else { w += 2; i += 4; } // 4字节字符 + } + return w; + }; + auto pad_left = [&](const std::string &s, int width) -> std::string { + int vw = visual_width(s); + int pad = width - vw; + if (pad > 0) return s + std::string(pad, ' '); + return s + ' '; + }; + + // 打印表头 + cout << "\t" + << pad_left("id", COL_ID) + << pad_left("saddr", COL_SADDR) + << pad_left("desc", COL_DESC) + << pad_left("type", COL_TYPE) + << pad_left("val", COL_VAL) + << pad_left("link_saddrs", COL_LINK) + << endl; + + // 打印分隔线 + int total_width = COL_ID + COL_SADDR + COL_DESC + COL_TYPE + COL_VAL + COL_LINK; + cout << "\t" << string(total_width, '-') << endl; + + // 遍历信号表 + // for(auto it = signal_map.begin(); it != signal_map.end(); ++it) + for(uint32_t i = 0; i < dc_signal_map.signal_id; i++) + { + // const stru_signal *p_signal = &it->second; + stru_signal *p_signal = dc_find_signal_by_id(i, dc_signal_map); + if(nullptr == p_signal) + { + MY_LOG_E("signal id %d not found", i); + continue; + } + + // 1. 先把所有列的内容拼接成字符串,再一次性输出,避免中间打断对齐 + string link_str; + bool first = true; + for (const auto &link : p_signal->link_saddrs) + { + if (!first) link_str += ", "; + link_str += link; + first = false; + } + + std::string val_str = dc_get_signal_val(p_signal->vec_p_data[0], p_signal->data_type); + + // 2. 输出所有列,按视觉宽度对齐 + cout << "\t" + << pad_left(std::to_string(p_signal->id), COL_ID) + << pad_left(p_signal->saddr, COL_SADDR) + << pad_left(p_signal->desc, COL_DESC) + << pad_left(dc_get_data_type_str_by_id(p_signal->data_type), COL_TYPE) + << pad_left(val_str, COL_VAL) + << pad_left(link_str, COL_LINK) + << endl; + + if (!cout.good()) break; + } + + if (!cout.good()) return; + + cout << endl; + + cout << "signal_id: " << dc_signal_map.signal_id << endl; + cout << "signal count: " << signal_map.size() << endl; + + cout << endl; +} + +uint32_t dc_get_signal_count(const char *type) +{ + if(nullptr == type) return 0; + if(0 == strcmp(type, "out")) return g_datacenter.signal_out.signal_id; + if(0 == strcmp(type, "in")) return g_datacenter.signal_in.signal_id; + if(0 == strcmp(type, "yk")) return g_datacenter.signal_yk.signal_id; + if(0 == strcmp(type, "ao")) return g_datacenter.signal_ao.signal_id; + if(0 == strcmp(type, "param")) return g_datacenter.signal_param.signal_id; + return 0; +} + +int dc_get_signal_info_by_id(const char *type, uint32_t id, std::string &saddr, std::string &desc, std::string &data_type, uint8_t &ctrl_type, std::vector &link_saddrs) +{ + if(nullptr == type) return -1; + + stru_signal *p_signal = nullptr; + if(0 == strcmp(type, "out")) p_signal = dc_find_signal_by_id(id, g_datacenter.signal_out); + if(0 == strcmp(type, "in")) p_signal = dc_find_signal_by_id(id, g_datacenter.signal_in); + if(0 == strcmp(type, "yk")) p_signal = dc_find_signal_by_id(id, g_datacenter.signal_yk); + if(0 == strcmp(type, "ao")) p_signal = dc_find_signal_by_id(id, g_datacenter.signal_ao); + if(0 == strcmp(type, "param")) p_signal = dc_find_signal_by_id(id, g_datacenter.signal_param); + if(nullptr == p_signal) + { + MY_LOG_E("signal id %d not found", id); + return -1; + } + + saddr = p_signal->saddr; + desc = p_signal->desc; + data_type = dc_get_data_type_str_by_id(p_signal->data_type); + ctrl_type = p_signal->ctrl_type; + link_saddrs = p_signal->link_saddrs; + return 0; +} + +LOCAL void dc_show_out_signals() +{ + using namespace std; + cout << "out signals: " << endl; + dc_show_signals(g_datacenter.signal_out); +} + +LOCAL void dc_show_in_signals() +{ + using namespace std; + + cout << "in signals: " << endl; + dc_show_signals(g_datacenter.signal_in); +} + +LOCAL void dc_show_yk_signals() +{ + using namespace std; + + cout << "yk signals: " << endl; + dc_show_signals(g_datacenter.signal_yk); +} + +LOCAL void dc_show_ao_signals() +{ + using namespace std; + + cout << "ao signals: " << endl; + dc_show_signals(g_datacenter.signal_ao); +} + + + +LOCAL void dc_show_param_signals() +{ + using namespace std; + + cout << "param signals: " << endl; + dc_show_signals(g_datacenter.signal_param); +} + + + +LOCAL void cmd_dc(int argc, char *argv[]) +{ + const char *str = "\ + datacenter out ----------> 查看out信号信息\n\ + datacenter in ----------> 查看in信号信息\n\ + datacenter yk ----------> 查看yk信号信息\n\ + datacenter ao ----------> 查看ao信号信息\n\ + datacenter param ----------> 查看param信号信息\n\ + datacenter all ----------> 查看所有信号信息\n"; + + + if(argc < 2) + { + printf("%s", str); + return; + } + + if(0 == strcmp(argv[1], "out")) + { + dc_show_out_signals(); + } + else if(0 == strcmp(argv[1], "in")) + { + dc_show_in_signals(); + } + else if(0 == strcmp(argv[1], "yk")) + { + dc_show_yk_signals(); + } + else if(0 == strcmp(argv[1], "ao")) + { + dc_show_ao_signals(); + } + else if(0 == strcmp(argv[1], "param")) + { + dc_show_param_signals(); + } + else if(0 == strcmp(argv[1], "all")) + { + dc_show_out_signals(); + dc_show_in_signals(); + dc_show_yk_signals(); + dc_show_ao_signals(); + dc_show_param_signals(); + } +} + +LOCAL void cmd_dc_complete(const char *buf, char ***completions, int *ncomp) +{ + static const char *subs[] = {"out", "in", "yk", "ao", "param", "all"}; + cmd_sub_complete(buf, completions, ncomp, subs, sizeof(subs)/sizeof(subs[0])); +} + +CMD_REGISTER_C("datacenter", cmd_dc, "数据中心的控制命令", cmd_dc_complete); + + diff --git a/src/public/libdatacenter/src/dc_signal_util.cpp b/src/public/libdatacenter/src/dc_signal_util.cpp new file mode 100644 index 0000000..0b7aab0 --- /dev/null +++ b/src/public/libdatacenter/src/dc_signal_util.cpp @@ -0,0 +1,484 @@ +#include "dc_signal_internal.h" + +LOCAL std::map g_data_type_str = { + {DATA_TYPE_B, "bool"}, + {DATA_TYPE_S8, "int8_t"}, + {DATA_TYPE_U8, "uint8_t"}, + {DATA_TYPE_S16, "int16_t"}, + {DATA_TYPE_U16, "uint16_t"}, + {DATA_TYPE_S32, "int32_t"}, + {DATA_TYPE_U32, "uint32_t"}, + {DATA_TYPE_L64, "int64_t"}, + {DATA_TYPE_UL64, "uint64_t"}, + {DATA_TYPE_F32, "float"}, + {DATA_TYPE_D64, "double"}, + {DATA_TYPE_IP, "ip"}, + {DATA_TYPE_MAC, "mac"}, + {DATA_TYPE_C8, "char8"}, + {DATA_TYPE_C32, "char32"}, + {DATA_TYPE_C64, "char64"}, + {DATA_TYPE_C128, "char128"}, + {DATA_TYPE_C1, "char1"}, + {DATA_TYPE_STR, "str"} +}; + +LOCAL std::map g_data_type_len = { + {DATA_TYPE_B, 1}, + {DATA_TYPE_S8, 1}, + {DATA_TYPE_U8, 1}, + {DATA_TYPE_S16, 2}, + {DATA_TYPE_U16, 2}, + {DATA_TYPE_S32, 4}, + {DATA_TYPE_U32, 4}, + {DATA_TYPE_L64, 8}, + {DATA_TYPE_UL64, 8}, + {DATA_TYPE_F32, 4}, + {DATA_TYPE_D64, 8}, + {DATA_TYPE_IP, 4}, + {DATA_TYPE_MAC, 8}, + {DATA_TYPE_C8, 8}, + {DATA_TYPE_C32, 32}, + {DATA_TYPE_C64, 64}, + {DATA_TYPE_C128, 128}, + {DATA_TYPE_C1, 1}, + {DATA_TYPE_STR, 128} +}; + +std::string dc_get_data_type_str_by_id(uint8_t data_type) +{ + auto it = g_data_type_str.find(data_type); + if(it != g_data_type_str.end()) + { + return it->second; + } + else + { + return "unknown"; + } +} + +uint8_t dc_get_data_type_id_by_str(const std::string &data_type_str) +{ + for(const auto &p : g_data_type_str) + { + if(p.second.compare(data_type_str) == 0) + { + return p.first; + } + } + return 0; +} + +uint8_t dc_get_data_type_len(uint8_t data_type) +{ + auto it = g_data_type_len.find(data_type); + if(it != g_data_type_len.end()) + { + return it->second; + } + else + { + return 0; + } +} + +std::string dc_get_signal_val(void *p_data, uint8_t data_type) +{ + if(NULL == p_data) + { + MY_LOG_E("p_data is nullptr"); + return ""; + } + + std::string str = ""; + char temp[128] = {0}; + char *ptr = NULL; + + switch(data_type) + { + case DATA_TYPE_B: + str = (*(int8_t *)p_data) > 0 ? "true" : "false"; + break; + case DATA_TYPE_S8: + str = std::to_string(*(int8_t *)p_data); + break; + case DATA_TYPE_U8: + str = std::to_string(*(uint8_t*)p_data); + break; + case DATA_TYPE_S16: + str = std::to_string(*(int16_t *)p_data); + break; + case DATA_TYPE_U16: + str = std::to_string(*(uint16_t*)p_data); + break; + case DATA_TYPE_S32: + str = std::to_string(*(int32_t *)p_data); + break; + case DATA_TYPE_U32: + str = std::to_string(*(uint32_t*)p_data); + break; + case DATA_TYPE_L64: + str = std::to_string(*(int64_t *)p_data); + break; + case DATA_TYPE_UL64: + str = std::to_string(*(uint64_t*)p_data); + break; + case DATA_TYPE_F32: + str = std::to_string(*(float*)p_data); + break; + case DATA_TYPE_D64: + str = std::to_string(*(double*)p_data); + break; + case DATA_TYPE_IP: + ptr = (char *)p_data; + snprintf(temp, 32, "%d.%d.%d.%d", (uint8_t)ptr[0], (uint8_t)ptr[1], (uint8_t)ptr[2], (uint8_t)ptr[3]); + str = std::string(temp); + break; + case DATA_TYPE_MAC: + ptr = (char *)p_data; + snprintf(temp, 32, "%02X:%02X:%02X:%02X:%02X:%02X", (uint8_t)ptr[0], (uint8_t)ptr[1], (uint8_t)ptr[2], (uint8_t)ptr[3], (uint8_t)ptr[4], (uint8_t)ptr[5]); + str = std::string(temp); + break; + case DATA_TYPE_C8: + case DATA_TYPE_C32: + case DATA_TYPE_C64: + case DATA_TYPE_C128: + // str = (char *)p_data; + snprintf(temp, dc_get_data_type_len(data_type), "%s", (char *)p_data); + str = std::string(temp); + break; + case DATA_TYPE_C1: + str = std::string(1, *(char*)p_data); + break; + case DATA_TYPE_STR: + snprintf(temp, dc_get_data_type_len(data_type), "%s", (char *)p_data); + str = std::string(temp); + break; + default: + break; + } + + return str; +} + +int dc_set_signal_val(void *p_data, uint8_t data_type, void *set_data) +{ + if(NULL == p_data || NULL == set_data) + { + LOG_E("p_data or str is NULL, p_data: %p, set_data: %p", p_data, set_data); + return -1; + } + + switch(data_type) + { + case DATA_TYPE_B: + *(int8_t *)p_data = ((char *)set_data)[0] & 0x01; + break; + case DATA_TYPE_S8: + *(int8_t *)p_data = *(int8_t *)set_data; + break; + case DATA_TYPE_U8: + *(uint8_t*)p_data = *(uint8_t*)set_data; + break; + case DATA_TYPE_S16: + *(int16_t *)p_data = *(int16_t *)set_data; + break; + case DATA_TYPE_U16: + *(uint16_t*)p_data = *(uint16_t*)set_data; + break; + case DATA_TYPE_S32: + *(int32_t *)p_data = *(int32_t *)set_data; + break; + case DATA_TYPE_U32: + *(uint32_t*)p_data = *(uint32_t*)set_data; + break; + case DATA_TYPE_L64: + *(int64_t *)p_data = *(int64_t *)set_data; + break; + case DATA_TYPE_UL64: + *(uint64_t*)p_data = *(uint64_t*)set_data; + break; + case DATA_TYPE_F32: + *(float*)p_data = *(float*)set_data; + break; + case DATA_TYPE_D64: + *(double*)p_data = *(double*)set_data; + break; + case DATA_TYPE_IP: + memcpy(p_data, set_data, 4); + break; + case DATA_TYPE_MAC: + memcpy(p_data, set_data, 6); + break; + case DATA_TYPE_C8: + case DATA_TYPE_C32: + case DATA_TYPE_C64: + case DATA_TYPE_C128: + case DATA_TYPE_STR: + memcpy(p_data, set_data, dc_get_data_type_len(data_type)); + break; + case DATA_TYPE_C1: + *(char*)p_data = *(char*)set_data; + break; + default: + LOG_E("unknown data_type: %d", data_type); + return -1; + } + + return 0; +} + +void dc_set_signal_val_from_str(void *p_data, uint8_t data_type, const std::string &str) +{ + if (str.empty() || p_data == nullptr) + { + MY_LOG_E("str is empty or p_data is nullptr"); + return; + } + + switch (data_type) + { + case DATA_TYPE_B: + *(uint8_t *)p_data = (str == "true" || str == "1") ? 1 : 0; + break; + case DATA_TYPE_S8: + *(int8_t *)p_data = (int8_t)std::stoi(str); + break; + case DATA_TYPE_U8: + *(uint8_t *)p_data = (uint8_t)std::stoul(str); + break; + case DATA_TYPE_S16: + *(int16_t *)p_data = (int16_t)std::stoi(str); + break; + case DATA_TYPE_U16: + *(uint16_t *)p_data = (uint16_t)std::stoul(str); + break; + case DATA_TYPE_S32: + *(int32_t *)p_data = std::stoi(str); + break; + case DATA_TYPE_U32: + *(uint32_t *)p_data = std::stoul(str); + break; + case DATA_TYPE_L64: + *(int64_t *)p_data = std::stoll(str); + break; + case DATA_TYPE_UL64: + *(uint64_t *)p_data = std::stoull(str); + break; + case DATA_TYPE_F32: + *(float *)p_data = std::stof(str); + break; + case DATA_TYPE_D64: + *(double *)p_data = std::stod(str); + break; + case DATA_TYPE_IP: + { + int a, b, c, d; + if (4 == sscanf(str.c_str(), "%d.%d.%d.%d", &a, &b, &c, &d)) + { + ((uint8_t *)p_data)[0] = (uint8_t)a; + ((uint8_t *)p_data)[1] = (uint8_t)b; + ((uint8_t *)p_data)[2] = (uint8_t)c; + ((uint8_t *)p_data)[3] = (uint8_t)d; + } + } + break; + case DATA_TYPE_MAC: + { + int m[6]; + if (6 == sscanf(str.c_str(), "%02X:%02X:%02X:%02X:%02X:%02X", &m[0], &m[1], &m[2], &m[3], &m[4], &m[5])) + { + for (int i = 0; i < 6; i++) + ((uint8_t *)p_data)[i] = (uint8_t)m[i]; + } + } + break; + case DATA_TYPE_C8: + case DATA_TYPE_C32: + case DATA_TYPE_C64: + case DATA_TYPE_C128: + case DATA_TYPE_STR: + strncpy((char *)p_data, str.c_str(), dc_get_data_type_len(data_type)); + break; + case DATA_TYPE_C1: + *(char *)p_data = str[0]; + break; + default: + LOG_E("unknown data_type: %d", data_type); + break; + } +} + +int dc_set_out_signal_val(const std::string &saddr, void *set_data, const std::string &module_id) +{ + stru_signal *p_signal = dc_find_out_signal(saddr); + if(p_signal != nullptr) + { + p_signal->last_caller_module = module_id; + dc_mark_signal_dirty(p_signal); + return dc_set_signal_val(p_signal->vec_p_data[0], p_signal->data_type, set_data); + } + + return -1; +} + +void *dc_create_data_ptr_by_type(uint8_t data_type) +{ + uint8_t *p_u8 = nullptr; + int8_t *p_s8 = nullptr; + int16_t *p_s16 = nullptr; + uint16_t *p_u16 = nullptr; + int32_t *p_s32 = nullptr; + uint32_t *p_u32 = nullptr; + int64_t *p_l64 = nullptr; + uint64_t *p_ul64 = nullptr; + float *p_f = nullptr; + double *p_d = nullptr; + char *p_char = nullptr; + + switch(data_type) + { + case DATA_TYPE_B: + p_u8 = new uint8_t; + (*p_u8) = 0; + return p_u8; + case DATA_TYPE_S8: + p_s8 = new int8_t; + (*p_s8) = 0; + return p_s8; + case DATA_TYPE_U8: + p_u8 = new uint8_t; + (*p_u8) = 0; + return p_u8; + case DATA_TYPE_S16: + p_s16 = new int16_t; + (*p_s16) = 0; + return p_s16; + case DATA_TYPE_U16: + p_u16 = new uint16_t; + (*p_u16) = 0; + return p_u16; + case DATA_TYPE_S32: + p_s32 = new int32_t; + (*p_s32) = 0; + return p_s32; + case DATA_TYPE_U32: + p_u32 = new uint32_t; + (*p_u32) = 0; + return p_u32; + case DATA_TYPE_L64: + p_l64 = new int64_t; + (*p_l64) = 0; + return p_l64; + case DATA_TYPE_UL64: + p_ul64 = new uint64_t; + (*p_ul64) = 0; + return p_ul64; + case DATA_TYPE_F32: + p_f = new float; + (*p_f) = 0.0; + return p_f; + case DATA_TYPE_D64: + p_d = new double; + (*p_d) = 0.0; + return p_d; + case DATA_TYPE_IP: + p_char = new char[4]; + memset(p_char, 0, 4); + return p_char; + case DATA_TYPE_MAC: + p_char = new char[8]; + memset(p_char, 0, 8); + return p_char; + case DATA_TYPE_C8: + p_char = new char[8]; + memset(p_char, 0, 8); + return p_char; + case DATA_TYPE_C32: + p_char = new char[32]; + memset(p_char, 0, 32); + return p_char; + case DATA_TYPE_C64: + p_char = new char[64]; + memset(p_char, 0, 64); + return p_char; + case DATA_TYPE_C128: + p_char = new char[128]; + memset(p_char, 0, 128); + return p_char; + case DATA_TYPE_C1: + p_char = new char[1]; + memset(p_char, 0, 1); + return p_char; + case DATA_TYPE_STR: + p_char = new char[128]; + memset(p_char, 0, 128); + return p_char; + default: + LOG_E("unknown data_type: %d", data_type); + return nullptr; + } +} + +void dc_delete_signal_data(void *p_data, uint8_t data_type) +{ + if(nullptr == p_data) return; + + switch(data_type) + { + case DATA_TYPE_B: + delete static_cast(p_data); + break; + case DATA_TYPE_S8: + delete static_cast(p_data); + break; + case DATA_TYPE_U8: + delete static_cast(p_data); + break; + case DATA_TYPE_S16: + delete static_cast(p_data); + break; + case DATA_TYPE_U16: + delete static_cast(p_data); + break; + case DATA_TYPE_S32: + delete static_cast(p_data); + break; + case DATA_TYPE_U32: + delete static_cast(p_data); + break; + case DATA_TYPE_L64: + delete static_cast(p_data); + break; + case DATA_TYPE_UL64: + delete static_cast(p_data); + break; + case DATA_TYPE_F32: + delete static_cast(p_data); + break; + case DATA_TYPE_D64: + delete static_cast(p_data); + break; + case DATA_TYPE_IP: + case DATA_TYPE_MAC: + case DATA_TYPE_C8: + case DATA_TYPE_C32: + case DATA_TYPE_C64: + case DATA_TYPE_C128: + case DATA_TYPE_C1: + case DATA_TYPE_STR: + delete [] static_cast(p_data); + break; + default: + MY_LOG_E("Unknown data_type %d for delete", data_type); + break; + } +} + + +stru_signal *dc_find_signal_by_id(uint32_t id, stru_signal_map &dc_signal_map) +{ + if (id < dc_signal_map.id_index.size()) + return dc_signal_map.id_index[id]; + return nullptr; +}