From 0fa7b700018b76ca0b8be80c1779c77d56e395ba Mon Sep 17 00:00:00 2001 From: ypc <15051963820@163.com> Date: Sat, 30 May 2026 14:13:49 +0800 Subject: [PATCH] =?UTF-8?q?<=E4=BF=AE=E6=94=B9>1=E3=80=81=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=95=B0=E6=8D=AE=E4=B8=AD=E5=BF=83=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=95=B0=E6=8D=AE=E5=AD=98=E5=82=A8=E5=86=85=E5=AD=98?= =?UTF-8?q?=E7=9A=84=E8=A1=A8=EF=BC=9B=202=E3=80=81=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=AE=9A=E5=80=BC=E5=88=9D=E5=A7=8B=E5=8C=96=E7=9A=84=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=EF=BC=8C=E4=BF=AE=E5=A4=8D=E4=BA=86=E9=87=8D=E5=90=AF?= =?UTF-8?q?=E5=90=8E=E5=AE=9A=E5=80=BC=E8=A1=A8=E4=B8=AD=E7=9A=84=E5=AE=9A?= =?UTF-8?q?=E5=80=BC=E6=81=A2=E5=A4=8D=E5=88=B0=E9=85=8D=E7=BD=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=B8=AD=E7=9A=84=E9=BB=98=E8=AE=A4=E5=80=BC=EF=BC=9B?= =?UTF-8?q?=203=E3=80=81=E8=B0=83=E6=95=B4mms=E5=AE=A2=E6=88=B7=E7=AB=AF?= =?UTF-8?q?=E7=9A=84=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=EF=BC=8Cmms?= =?UTF-8?q?=E7=9A=84=E4=BF=A1=E5=8F=B7=E8=B7=AF=E5=BE=84=E5=BF=85=E9=A1=BB?= =?UTF-8?q?=E5=88=B0=E6=9C=80=E4=B8=8B=E5=B1=82=E3=80=82=204=E3=80=81?= =?UTF-8?q?=E8=B0=83=E6=95=B4mms=E5=AE=A2=E6=88=B7=E7=AB=AF=E5=BA=93?= =?UTF-8?q?=EF=BC=8C=E5=AE=9A=E5=80=BC=E5=92=8C=E5=8F=82=E6=95=B0=E7=9A=84?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E7=94=B1=E8=8E=B7=E5=8F=96=E5=88=B0=E7=9A=84?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E4=B8=BA=E5=87=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- src/protocol/libmms_m/src/mms_m.cpp | 30 +- src/protocol/libmms_s/src/mms_s_value.cpp | 5 +- src/system/libdatacenter/inc/dc_signal.h | 3 +- src/system/libdatacenter/src/dc_signal.cpp | 355 +++++++++------------ src/system/libiec61850m/src/iec61850m.cpp | 6 +- test/file/MMS/prj.xml | 2 +- 7 files changed, 182 insertions(+), 222 deletions(-) diff --git a/.gitignore b/.gitignore index fe25683..72490aa 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,5 @@ release/x86/ release/arm/ src/system/uart_trans/ src/system/FTU_cfg_parse/ -libiec61850-1.5.3/ \ No newline at end of file +libiec61850-1.5.3/ +doc/ \ No newline at end of file diff --git a/src/protocol/libmms_m/src/mms_m.cpp b/src/protocol/libmms_m/src/mms_m.cpp index ec291f5..c519b3b 100644 --- a/src/protocol/libmms_m/src/mms_m.cpp +++ b/src/protocol/libmms_m/src/mms_m.cpp @@ -104,7 +104,7 @@ static void mms_m_put_value(stru_mms_m_obj &obj, stru_mms_m_out_value &out_value } } -static void mms_m_show_MmsValue(MmsValue* mms_value) +static void mms_m_show_MmsValue(MmsValue* mms_value, uint8_t *p_out_mms_type) { if(NULL == mms_value) { @@ -118,10 +118,17 @@ static void mms_m_show_MmsValue(MmsValue* mms_value) float fVal; MmsType mmsType = MmsValue_getType(mms_value); + + LOG_I("show_mms_value mmsType %d", mmsType); + if(NULL != p_out_mms_type) + { + *p_out_mms_type = mmsType; + } + switch(mmsType) { case MMS_STRUCTURE: - return mms_m_show_MmsValue(MmsValue_getElement(mms_value, 0)); + return mms_m_show_MmsValue(MmsValue_getElement(mms_value, 0), p_out_mms_type); break; case MMS_BOOLEAN: bVal = MmsValue_getBoolean(mms_value); @@ -144,6 +151,7 @@ static void mms_m_show_MmsValue(MmsValue* mms_value) LOG_I("show_mms_value fVal: %f\n", fVal); break; case MMS_STRING: + case MMS_VISIBLE_STRING: strVal= (char *)MmsValue_toString(mms_value); LOG_I("show_mms_value strVal %s\r\n", strVal); break; @@ -213,7 +221,7 @@ static int mms_m_param_value_sync(stru_point_item &item, stru_mms_m_event &event { if(item.type != event.value_type) { - LOG_E("value type not match"); + LOG_E("value type not match, item.type = %d, event.value_type = %d", item.type, event.value_type); return -1; } @@ -239,6 +247,9 @@ static int mms_m_param_value_sync(stru_point_item &item, stru_mms_m_event &event case MMS_STRING: item.set_value = MmsValue_newMmsString((char *)event.val); break; + case MMS_VISIBLE_STRING: + item.set_value = MmsValue_newVisibleString((char *)event.val); + break; default: LOG_E("value type not support"); return -1; @@ -264,6 +275,9 @@ static int mms_m_param_value_sync(stru_point_item &item, stru_mms_m_event &event case MMS_STRING: MmsValue_setMmsString(item.set_value, (char *)event.val); break; + case MMS_VISIBLE_STRING: + MmsValue_setVisibleString(item.set_value, (char *)event.val); + break; default: LOG_E("value type not support"); return -1; @@ -304,7 +318,7 @@ static int mms_m_send_ao_write(stru_mms_m_obj &obj, stru_mms_m_event &event) { // if(MMS_M_DEBUG_PRINT_ON == obj.debug_print_flag) { - mms_m_show_MmsValue(p_value); + mms_m_show_MmsValue(p_value, &p_item->type); } } else @@ -364,7 +378,7 @@ static int mms_m_send_param_write(stru_mms_m_obj &obj, stru_mms_m_event &event) { if(MMS_M_DEBUG_PRINT_ON == obj.debug_print_flag) { - mms_m_show_MmsValue(p_value); + mms_m_show_MmsValue(p_value, &p_item->type); } } else @@ -457,7 +471,7 @@ static void mms_m_send_read_ao(stru_mms_m_obj &obj, stru_mms_m_event &event) if(MMS_M_DEBUG_PRINT_ON == obj.debug_print_flag) { - mms_m_show_MmsValue(p_value); + mms_m_show_MmsValue(p_value, &p_item->type); } void *p_val = event.set_zone >= p_item->value.vec_p_val.size() ? NULL : p_item->value.vec_p_val[event.set_zone]; @@ -551,7 +565,7 @@ static int mms_m_send_co_select(stru_mms_m_obj &obj, stru_point_item &item) if(MMS_M_DEBUG_PRINT_ON == obj.debug_print_flag) { - mms_m_show_MmsValue(item.set_value); + mms_m_show_MmsValue(item.set_value, &item.type); } if (ControlObjectClient_selectWithValue(item.control, item.set_value)) @@ -758,7 +772,7 @@ static void mms_m_send_call_all(stru_mms_m_obj &obj) if(MMS_M_DEBUG_PRINT_ON == obj.debug_print_flag) { - mms_m_show_MmsValue(p_value); + mms_m_show_MmsValue(p_value, &it->type); } if(0 != mms_m_get_mmsValue(p_value, it->type, it->value.vec_p_val[0])) diff --git a/src/protocol/libmms_s/src/mms_s_value.cpp b/src/protocol/libmms_s/src/mms_s_value.cpp index dbfaeff..00dc24d 100644 --- a/src/protocol/libmms_s/src/mms_s_value.cpp +++ b/src/protocol/libmms_s/src/mms_s_value.cpp @@ -412,7 +412,10 @@ LOCAL void mms_s_da_value_init_Dbpos(DataAttribute *da, void *value) Dbpos_toMmsValue(da->mmsValue, pos); - LOG_I("da %s-%s, value %s, pos %d", da->parent->name, da->name, (char *)value, pos); + if(mms_s_dbg_get()) + { + LOG_I("da %s-%s, value %s, pos %d", da->parent->name, da->name, (char *)value, pos); + } } /** diff --git a/src/system/libdatacenter/inc/dc_signal.h b/src/system/libdatacenter/inc/dc_signal.h index 7c9a741..b7d1f06 100644 --- a/src/system/libdatacenter/inc/dc_signal.h +++ b/src/system/libdatacenter/inc/dc_signal.h @@ -7,6 +7,7 @@ #include #include #include +#include typedef struct stru_signal @@ -21,7 +22,7 @@ typedef struct stru_signal void *p_last_data; // 上一次数据指针 std::vector vec_p_default_data; // 默认值指针列表(支持多条目) std::vector link_saddrs; - // stru_signal_ctrl ctrl; // 信号扩展信息 + std::unordered_set link_set; // O(1) 查重 uint8_t ctrl_type; // 信号控制类型 stru_signal_param param; // 信号参数信息 std::vector out_change_cb_list; // 输出类型信号变化回调函数列表 diff --git a/src/system/libdatacenter/src/dc_signal.cpp b/src/system/libdatacenter/src/dc_signal.cpp index c07e32c..4c2574c 100644 --- a/src/system/libdatacenter/src/dc_signal.cpp +++ b/src/system/libdatacenter/src/dc_signal.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include "dc_signal.h" #include "dc_param.h" @@ -36,7 +36,7 @@ struct XXH128Equal { } }; -typedef std::unordered_map hash_signal_map; +typedef std::unordered_multimap hash_signal_map; typedef struct @@ -44,9 +44,7 @@ typedef struct std::mutex mtx; uint32_t signal_id; hash_signal_map map_signals; - std::unordered_map, XXH128Hash, XXH128Equal> hash_conflict_table; - std::unordered_map hash_index; - std::unordered_map, XXH128Hash, XXH128Equal> hash_conflicts; + std::vector id_index; // ID→指针 O(1) 索引 }stru_signal_map; @@ -65,11 +63,22 @@ 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) +{ + 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 XXH128_hash_t &hash, stru_signal_map &dc_signal_map); +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); @@ -153,7 +162,7 @@ int dc_get_in_signal_info(const std::string &saddr, std::string &desc, uint8_t & 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, void **p_default_data) { - stru_signal *p_signal = dc_find_signal(XXH3_128bits(saddr.c_str(), saddr.length()), g_datacenter.signal_ao); + 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()); @@ -202,7 +211,7 @@ int dc_get_ao_signal_info(const std::string &saddr, std::string &desc, uint8_t & 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, std::vector *p_vec_p_default_data) { - stru_signal *p_signal = dc_find_signal(XXH3_128bits(saddr.c_str(), saddr.length()), g_datacenter.signal_param); + 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()); @@ -251,7 +260,7 @@ int dc_get_param_signal_info(const std::string &saddr, std::string &desc, uint8_ 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(XXH3_128bits(saddr.c_str(), saddr.length()), g_datacenter.signal_yk); + 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()); @@ -271,19 +280,33 @@ int dc_get_yk_signal_info(const std::string &saddr, std::string &desc, uint8_t & void dc_signal_out_change_check() { - for(auto it = g_datacenter.signal_out.map_signals.begin(); it != g_datacenter.signal_out.map_signals.end(); it++) + std::vector dirty; { - stru_signal *p_signal = &it->second; - 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 cb : p_signal->out_change_cb_list) - { - cb(p_signal->saddr, p_signal->data_type, p_signal->vec_p_data[0], p_signal->p_last_data); - } + std::lock_guard lock(g_dirty_out_mutex); + dirty.swap(g_dirty_out_signals); + } - dc_set_signal_val(p_signal->p_last_data, p_signal->data_type, p_signal->vec_p_data[0]); + 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 cb : p_signal->out_change_cb_list) { + cb(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]); } } } @@ -347,11 +370,11 @@ LOCAL int dc_data_compare(uint8_t data_type, void *p_data, void *p_data2) return -1; } -LOCAL bool dc_signal_ao_add_check(stru_signal *p_signal, const std::string &desc, uint8_t data_type, const stru_signal_param ¶m, uint8_t ctrl_type, void *p_data, void *p_default_data) +LOCAL bool dc_signal_ao_add_check(stru_signal *p_signal, const std::string &desc, uint8_t data_type, const stru_signal_param ¶m, uint8_t ctrl_type, void *p_default_data) { - if(p_signal == nullptr || p_data == nullptr || p_default_data == nullptr) + if(p_signal == nullptr || p_default_data == nullptr) { - LOG_E("p_signal, p_data or p_default_data is nullptr"); + LOG_E("p_signal or p_default_data is nullptr"); return false; } @@ -389,7 +412,7 @@ LOCAL bool dc_signal_ao_add_check(stru_signal *p_signal, const std::string &desc return change; } -LOCAL bool dc_signal_param_add_check(stru_signal *p_signal, const std::string &desc, uint8_t data_type, const stru_signal_param ¶m, uint8_t ctrl_type, std::vector &vec_p_data, std::vector &vec_p_default_data) +LOCAL bool dc_signal_param_add_check(stru_signal *p_signal, const std::string &desc, uint8_t data_type, const stru_signal_param ¶m, uint8_t ctrl_type, std::vector &vec_p_default_data) { bool change = false; @@ -417,17 +440,9 @@ LOCAL bool dc_signal_param_add_check(stru_signal *p_signal, const std::string &d change = true; } - // for(size_t i = 0; i < vec_p_default_data.size(); i++) - // { - // if(0 != dc_data_compare(p_signal->data_type, vec_p_default_data[i], p_signal->vec_p_default_data[i])) - // { - // change = true; - // } - // } - - for(size_t i = 0; i < vec_p_data.size(); i++) + for(size_t i = 0; i < vec_p_default_data.size(); i++) { - if(0 != dc_data_compare(p_signal->data_type, vec_p_data[i], p_signal->vec_p_data[i])) + if(0 != dc_data_compare(p_signal->data_type, vec_p_default_data[i], p_signal->vec_p_default_data[i])) { change = true; } @@ -839,89 +854,30 @@ LOCAL int dc_check_val_valid(const stru_signal *p_signal, uint8_t setting_zone, -LOCAL void dc_update_global_index(const stru_signal &signal, stru_signal_map &dc_signal_map) -{ - auto it = dc_signal_map.hash_index.find(signal.hash); - if(it != dc_signal_map.hash_index.end()) - { - if(it->second != signal.saddr) - { - MY_LOG_E("hash collision: %s -> %s", it->second.c_str(), signal.saddr.c_str()); - dc_signal_map.hash_conflicts[signal.hash].push_back(it->second); - dc_signal_map.hash_conflicts[signal.hash].push_back(signal.saddr); - } - } - else - { - dc_signal_map.hash_index.emplace(signal.hash, signal.saddr); - } -} - - LOCAL int dc_signal_add_to_map(stru_signal &signal, stru_signal_map &dc_signal_map) { std::lock_guard lock(dc_signal_map.mtx); - hash_signal_map &signal_map = dc_signal_map.map_signals; - auto conflict_it = dc_signal_map.hash_conflict_table.find(signal.hash); - if (conflict_it != dc_signal_map.hash_conflict_table.end()) - { - for(stru_signal *exist_signal : conflict_it->second) - { - if(exist_signal->saddr == signal.saddr) - { - uint32_t old_id = exist_signal->id; - *exist_signal = signal; - exist_signal->id = old_id; - return 0; - } - } - auto [it, inserted] = signal_map.emplace(signal.hash, signal); - stru_signal *new_sig = &it->second; - new_sig->id = dc_signal_map.signal_id++; - conflict_it->second.push_back(new_sig); - - dc_update_global_index(*new_sig, dc_signal_map); - } - else - { - auto map_it = signal_map.find(signal.hash); - if(map_it != signal_map.end()) - { - if(map_it->second.saddr != signal.saddr) - { - std::vector conficts; - conficts.push_back(&map_it->second); - - auto [it, inserted] = signal_map.emplace(signal.hash, signal); - stru_signal *new_sig = &it->second; - new_sig->id = dc_signal_map.signal_id++; - - conficts.push_back(new_sig); - dc_signal_map.hash_conflict_table[signal.hash] = conficts; - - dc_update_global_index(*new_sig, dc_signal_map); - return 0; - } - else - { - auto old_id = map_it->second.id; - map_it->second = signal; - map_it->second.id = old_id; - return 0; - } - } - else - { - auto [it, inserted] = signal_map.emplace(signal.hash, signal); - stru_signal &new_sig = it->second; - new_sig.id = dc_signal_map.signal_id++; - - dc_update_global_index(new_sig, dc_signal_map); + // 先查找是否已有相同 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; } @@ -1034,18 +990,9 @@ int dc_signal_in(const std::string &saddr, const std::string &desc, const std::s signal.data_type = p_signal_out->data_type; signal.vec_p_data.push_back((*p_data)); - bool found = false; - for(auto it = p_signal_out->link_saddrs.begin(); it != p_signal_out->link_saddrs.end(); ++it) - { - if(it->compare(saddr) == 0) - { - found = true; - break; - } - } - - if(!found) + 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); } @@ -1096,7 +1043,11 @@ int dc_signal_in_with_callback(const std::string &saddr, const std::string &desc p_signal_out->out_change_cb_list.push_back(cb); } - p_signal_out->link_saddrs.push_back(saddr); + 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); @@ -1112,10 +1063,10 @@ int dc_signal_ao(const std::string &saddr, const std::string &desc, uint8_t data } XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_ao); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao); if(p_signal != nullptr && !p_signal->vec_p_data.empty() && !p_signal->vec_p_default_data.empty() && nullptr != p_signal->vec_p_data[0] && nullptr != p_signal->vec_p_default_data[0]) { - if(true == dc_signal_ao_add_check(p_signal, desc, data_type, param, ctrl_type, p_data, p_default_data)) + if(true == dc_signal_ao_add_check(p_signal, desc, data_type, param, ctrl_type, p_default_data)) { dc_set_param_cfg_change(true); } @@ -1144,7 +1095,7 @@ int dc_signal_ao(const std::string &saddr, const std::string &desc, uint8_t data dc_signal_add_to_map(signal, g_datacenter.signal_ao); - p_signal = dc_find_signal(hash, 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); @@ -1170,7 +1121,7 @@ int dc_signal_ao_link_with_callback(const std::string &saddr, void **p_data, sig } XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_ao); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao); if(p_signal != nullptr) { if(cb) @@ -1194,7 +1145,7 @@ int dc_signal_ao_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_s } XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_ao); + 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)) @@ -1260,7 +1211,7 @@ int dc_signal_ao_set_val_without_check(const std::string &saddr, uint8_t data_ty } XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_ao); + 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) @@ -1305,11 +1256,11 @@ int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t d } XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_param); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param); if(p_signal != nullptr) { // dc_set_signal_val(p_data, data_type, p_signal->p_data); - if(true == dc_signal_param_add_check(p_signal, desc, data_type, param, ctrl_type, vec_p_data, vec_p_default_data)) + if(true == dc_signal_param_add_check(p_signal, desc, data_type, param, ctrl_type, vec_p_default_data)) { dc_set_param_cfg_change(true); } @@ -1354,7 +1305,7 @@ int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t d dc_signal_add_to_map(signal, g_datacenter.signal_param); - p_signal = dc_find_signal(hash, g_datacenter.signal_param); + p_signal = dc_find_signal(saddr, g_datacenter.signal_param); if(p_signal != nullptr ) { for(size_t i = 0; i < vec_p_data.size(); i++) @@ -1376,7 +1327,7 @@ int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t d int dc_signal_param_link_with_callback(const std::string &saddr, std::vector &vec_p_data, signal_change_cb cb) { XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_param); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param); if(p_signal != nullptr) { // if(p_signal->data_type != data_type) @@ -1411,7 +1362,7 @@ int dc_signal_param_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, str } XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_param); + 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)) @@ -1476,7 +1427,7 @@ int dc_signal_param_set_val_without_check(const std::string &saddr, uint8_t data } XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_param); + 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) @@ -1513,7 +1464,7 @@ int dc_signal_yk(const std::string &saddr, const std::string &desc, uint8_t data dc_signal_add_to_map(signal, g_datacenter.signal_yk); - stru_signal *p_signal = dc_find_signal(signal.hash, g_datacenter.signal_yk); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_yk); if(p_signal != nullptr) { if(cb) @@ -1538,7 +1489,7 @@ int dc_signal_yk_link_with_callback(const std::string &saddr, void **p_data, sig } XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_yk); + stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_yk); if(p_signal != nullptr) { if(cb) @@ -1561,7 +1512,7 @@ int dc_signal_yk_set_status(const std::string &saddr, SIGNAL_CTRL_STEP step, str } XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_yk); + 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)) @@ -1610,35 +1561,29 @@ int dc_signal_yk_set_status(const std::string &saddr, SIGNAL_CTRL_STEP step, str } -LOCAL stru_signal* dc_find_signal(const XXH128_hash_t &hash, stru_signal_map &dc_signal_map) +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); - hash_signal_map &signal_map = dc_signal_map.map_signals; - auto map_it = signal_map.find(hash); - if(map_it != signal_map.end()) - { - return &map_it->second; - } - else - { - return nullptr; + 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) { - XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - - return dc_find_signal(hash, g_datacenter.signal_out); + return dc_find_signal(saddr, g_datacenter.signal_out); } LOCAL stru_signal* dc_find_in_signal(const std::string &saddr) { - XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - - return dc_find_signal(hash, g_datacenter.signal_in); + return dc_find_signal(saddr, g_datacenter.signal_in); } LOCAL std::map g_data_type_str = { @@ -1955,6 +1900,7 @@ int dc_set_out_signal_val(const std::string &saddr, void *set_data) stru_signal *p_signal = dc_find_out_signal(saddr); if(p_signal != nullptr) { + dc_mark_signal_dirty(p_signal); return dc_set_signal_val(p_signal->vec_p_data[0], p_signal->data_type, set_data); } @@ -2117,13 +2063,8 @@ void dc_delete_signal_data(void *p_data, uint8_t data_type) LOCAL stru_signal *dc_find_signal_by_id(uint32_t id, stru_signal_map &dc_signal_map) { - for(auto it = dc_signal_map.map_signals.begin(); it != dc_signal_map.map_signals.end(); ++it) - { - if(it->second.id == id) - { - return &it->second; - } - } + if (id < dc_signal_map.id_index.size()) + return dc_signal_map.id_index[id]; return nullptr; } @@ -2196,7 +2137,7 @@ void dc_param_cfg_check() { XMLElement *item_elem = doc.NewElement("Item"); item_elem->SetAttribute("index", i+1); - item_elem->SetAttribute("val", dc_get_signal_val(p_param->vec_p_data[i], p_param->data_type).c_str()); + item_elem->SetAttribute("value", dc_get_signal_val(p_param->vec_p_data[i], p_param->data_type).c_str()); item_elem->SetAttribute("default", dc_get_signal_val(p_param->vec_p_default_data[i], p_param->data_type).c_str()); sig_elem->InsertEndChild(item_elem); @@ -2226,27 +2167,46 @@ LOCAL void dc_show_signals(stru_signal_map &dc_signal_map) hash_signal_map &signal_map = dc_signal_map.map_signals; - // 定义列宽(单位:字符,考虑中英文混合) - const int COL_ID = 12; - const int COL_SADDR = 48; - const int COL_DESC = 64; - const int COL_TYPE = 12; - const int COL_VAL = 32; - const int COL_LINK = 64; + // 定义列宽(单位:终端视觉列数,中文占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; - // 打印表头(严格对齐,使用left对齐) + // 按终端视觉宽度左对齐辅助函数 + 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" - << left - << setw(COL_ID) << "id" - << setw(COL_SADDR) << "saddr" - << setw(COL_DESC) << "desc" - << setw(COL_TYPE) << "data_type" - << setw(COL_VAL) << "val" - << setw(COL_LINK) << "link_saddrs" + << 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_SADDR + COL_DESC + COL_TYPE + COL_VAL + COL_LINK; + // 打印分隔线 + int total_width = COL_ID + COL_SADDR + COL_DESC + COL_TYPE + COL_VAL + COL_LINK; cout << "\t" << string(total_width, '-') << endl; // 遍历信号表 @@ -2261,7 +2221,7 @@ LOCAL void dc_show_signals(stru_signal_map &dc_signal_map) continue; } - // 1. 先把所有列的内容拼接成字符串,再一次性输出,避免中间打断setw对齐 + // 1. 先把所有列的内容拼接成字符串,再一次性输出,避免中间打断对齐 string link_str; bool first = true; for (const auto &link : p_signal->link_saddrs) @@ -2271,15 +2231,16 @@ LOCAL void dc_show_signals(stru_signal_map &dc_signal_map) first = false; } - // 2. 输出所有列,严格使用setw控制宽度 + std::string val_str = dc_get_signal_val(p_signal->vec_p_data[0], p_signal->data_type); + + // 2. 输出所有列,按视觉宽度对齐 cout << "\t" - << left - << setw(COL_ID) << p_signal->id - << setw(COL_SADDR) << p_signal->saddr - << setw(COL_DESC) << p_signal->desc - << setw(COL_TYPE) << dc_get_data_type_str_by_id(p_signal->data_type) - << setw(COL_VAL) << dc_get_signal_val(p_signal->vec_p_data[0], p_signal->data_type) - << setw(COL_LINK) << link_str + << 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; } @@ -2287,26 +2248,6 @@ LOCAL void dc_show_signals(stru_signal_map &dc_signal_map) cout << "signal_id: " << dc_signal_map.signal_id << endl; cout << "signal count: " << signal_map.size() << endl; - cout << "conflict count: " << dc_signal_map.hash_conflicts.size() << endl; - - if(dc_signal_map.hash_conflicts.empty()) - { - cout << "no conflict" << endl; - } - else - { - cout << "conflicts: count " << dc_signal_map.hash_conflicts.size() << endl; - for(auto it = dc_signal_map.hash_conflicts.begin(); it != dc_signal_map.hash_conflicts.end(); ++it) - { - const auto &hash = it->first; - const auto &saddrs = it->second; - cout << " hash: " << hash.low64 << "-" << hash.high64 << " num: " << saddrs.size() << endl; - for(auto &saddr : saddrs) - { - cout << " " << saddr.c_str() << endl; - } - } - } cout << endl; } diff --git a/src/system/libiec61850m/src/iec61850m.cpp b/src/system/libiec61850m/src/iec61850m.cpp index d2759de..542685d 100644 --- a/src/system/libiec61850m/src/iec61850m.cpp +++ b/src/system/libiec61850m/src/iec61850m.cpp @@ -38,7 +38,7 @@ LOCAL std::map g_mms_m_type_to_local_type = { {MMS_UNSIGNED, DATA_TYPE_U32}, {MMS_FLOAT, DATA_TYPE_F32}, {MMS_STRING, DATA_TYPE_STR}, - {MMS_VISIBLE_STRING, DATA_TYPE_STR}, + // {MMS_VISIBLE_STRING, DATA_TYPE_STR}, }; LOCAL std::map g_mms_m_ctrl_type_to_local_ctrl_type = { @@ -251,7 +251,7 @@ LOCAL int iec61850m_signal_change_decode(std::string saddr, SIGNAL_CTRL_STEP ste std::string data_type_str = ""; data_type_str = dc_get_data_type_str_by_id(data_type); - MY_LOG_I("iec61850m_signal_change_callback saddr %s, step %s, data_type %s, value %s", saddr.c_str(), step_str.c_str(), data_type_str.c_str(), value.c_str()); + MY_LOG_I("iec61850m_signal_change_callback saddr %s, step %s, data_type %s, mms_type %d, value %s", saddr.c_str(), step_str.c_str(), data_type_str.c_str(), mms_type, value.c_str()); return 0; } @@ -308,7 +308,7 @@ LOCAL void iec61850m_signal_ao_change_callback(std::string saddr, SIGNAL_CTRL_ST if(p_config->p_ao_sig[j].sig.saddr == saddr) { std::string val = dc_get_signal_val(p_data, data_type); - MY_LOG_I("iec61850m_signal_change_callback val %s, ctrl_type %d", val.c_str(), ctrl_type); + MY_LOG_I("iec61850m_signal_change_callback val %s, ctrl_type %d, mms_type %d", val.c_str(), ctrl_type, mms_type); mms_send_control(p_info->fd, saddr.c_str(), val.c_str(), mms_type, ctrl_type, 0); } } diff --git a/test/file/MMS/prj.xml b/test/file/MMS/prj.xml index ac137d8..1306190 100644 --- a/test/file/MMS/prj.xml +++ b/test/file/MMS/prj.xml @@ -26,7 +26,7 @@ - +