diff --git a/.vscode/settings.json b/.vscode/settings.json index b49385a..885109a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,5 @@ { "makefile.makefilePath": "/mnt/RTU/release/", - "cmake.sourceDirectory": "/mnt/RTU/libiec61850-1.5.3/demos/beaglebone" + "cmake.sourceDirectory": "/mnt/RTU/libiec61850-1.5.3/demos/beaglebone", + "terminal.integrated.scrollback": 10000 } \ No newline at end of file diff --git a/release/inc/myIcp67.h b/release/inc/myIcp67.h index 68460ac..493b996 100644 --- a/release/inc/myIcp67.h +++ b/release/inc/myIcp67.h @@ -163,9 +163,9 @@ typedef int (*icp67_search_frame_cb)(uint8_t *p_data, uint16_t len, uint16_t *p_ typedef int (*icp67_decode_cb)(stru_icp67 *p_icp67, uint8_t *p_rx, uint16_t rx_len); typedef void (*icp67_timer_handler_cb)(stru_icp67 *p_icp67); -typedef void (*icp67_param_get_cb)(stru_icp67 *p_icp67, stru_ti_1_2_data *p_data, uint16_t num); -typedef void (*icp67_param_pop_out_cb)(stru_icp67 *p_icp67, uint16_t addr, uint8_t type, uint8_t len, uint8_t *p_data); -typedef void (*icp67_param_set_cb)(stru_icp67 *p_icp67, uint8_t *p_data, uint16_t num); +typedef void (*icp67_ao_get_cb)(stru_icp67 *p_icp67, stru_ti_1_2_data *p_data, uint16_t num); +typedef void (*icp67_ao_pop_out_cb)(stru_icp67 *p_icp67, uint16_t addr, uint8_t type, uint8_t len, uint8_t *p_data); +typedef void (*icp67_ao_set_cb)(stru_icp67 *p_icp67, uint8_t *p_data, uint16_t num); typedef void (*icp67_iec_point_tbl_get_cb)(stru_icp67 *p_icp67, uint16_t info_addr); typedef void (*icp67_iec_point_tbl_pop_out_cb)(stru_icp67 *p_icp67, uint16_t info_addr, uint16_t num, uint8_t *p_data); typedef void (*icp67_time_set_cb)(stru_icp67 *p_icp67, stru_ti_5 *p_time); @@ -198,9 +198,9 @@ typedef void (*icp67_mx_change_cb)(stru_icp67 *p_icp67, stru_mx_info *p_data); typedef struct { - icp67_param_get_cb param_get_cb; // 内部参数读取回调函数 - icp67_param_pop_out_cb param_pop_out_cb; // 内部参数读取出回调函数 - icp67_param_set_cb param_set_cb; // 外部修改参数设置的回调函数 + icp67_ao_get_cb ao_get_cb; // 内部参数读取回调函数 + icp67_ao_pop_out_cb ao_pop_out_cb; // 内部参数读取出回调函数 + icp67_ao_set_cb ao_set_cb; // 外部修改参数设置的回调函数 icp67_iec_point_tbl_get_cb iec_point_tbl_get_cb; // 内部IEC表读取回调函数 icp67_iec_point_tbl_pop_out_cb iec_point_tbl_pop_out_cb; // 内部IEC表读取出回调函数 icp67_time_set_cb time_set_cb; // 时间设置回调函数 @@ -233,9 +233,9 @@ typedef struct }stru_genneral_method; -extern void icp67_set_param_get_cb(icp67_param_get_cb *p_cb); // 设置参数获取回调函数 -extern void icp67_set_param_pop_out_cb(icp67_param_pop_out_cb cb); // 设置参数数据返回回调函数 -extern void icp67_set_param_set_cb(icp67_param_set_cb *p_cb); // 设置参数设置回调函数 +extern void icp67_set_ao_get_cb(icp67_ao_get_cb *p_cb); // 设置参数获取回调函数 +extern void icp67_set_ao_pop_out_cb(icp67_ao_pop_out_cb cb); // 设置参数数据返回回调函数 +extern void icp67_set_ao_set_cb(icp67_ao_set_cb *p_cb); // 设置参数设置回调函数 extern void icp67_set_iec_point_tbl_get_cb(icp67_iec_point_tbl_get_cb *p_cb); // 设置iec点表获取回调函数 extern void icp67_set_iec_point_tbl_pop_out_cb(icp67_iec_point_tbl_pop_out_cb cb); // 设置iec点表数据返回回调函数 extern void icp67_set_time_set_cb(icp67_time_set_cb *p_cb); // 设置时间设置回调函数 @@ -292,6 +292,6 @@ typedef struct _icp67 void icp67_init(stru_icp67 *p_icp67, icp67_send_cb send_cb, void *arg); -int icp67_set_param_cfg_md5(stru_icp67 *p_icp67, uint8_t *p_md5); +int icp67_set_ao_cfg_md5(stru_icp67 *p_icp67, uint8_t *p_md5); diff --git a/release/inc/myMms_m.h b/release/inc/myMms_m.h index 865e27b..bccb36c 100644 --- a/release/inc/myMms_m.h +++ b/release/inc/myMms_m.h @@ -75,7 +75,8 @@ typedef struct char saddr[MMS_M_STR_LEN]; char desc[MMS_M_STR_LEN]; uint8_t data_type; - void *p_data; + // void *p_data; + std::vector vec_p_data; }stru_mms_m_gen_signal; typedef struct @@ -92,7 +93,8 @@ typedef struct double max; double step; char unit[MMS_M_STR_LEN]; - void *p_default; + // void *p_default; + std::vector vec_p_default; }stru_mms_m_param_signal; typedef struct @@ -101,10 +103,12 @@ typedef struct uint16_t mx_num; uint16_t co_num; uint16_t ao_num; + uint16_t param_num; stru_mms_m_gen_signal *p_st_sig; stru_mms_m_gen_signal *p_mx_sig; stru_mms_m_ctrl_signal *p_co_sig; stru_mms_m_param_signal *p_ao_sig; + stru_mms_m_param_signal *p_param_sig; }stru_mms_m_config; @@ -174,6 +178,7 @@ char *mms_m_out_reason_str(int reason); void *mms_m_create_data_ptr(uint8_t type); int mms_m_set_data_value(void *srt, void *dst, uint8_t type); int mms_m_get_data_value_str(void *data, uint8_t type, char *str); +int mms_m_set_data_by_str(void *data, uint8_t type, const char *str); #ifdef __cplusplus } diff --git a/release/inc/mySystem.h b/release/inc/mySystem.h index 1e0bb33..1aeb0bb 100644 --- a/release/inc/mySystem.h +++ b/release/inc/mySystem.h @@ -253,11 +253,13 @@ typedef struct { stru_self_ptl_cfg_base base; uint8_t type; - std::string default_value; + uint8_t num; std::string unit; std::string min; std::string max; std::string step; + std::vector val; + std::vector default_value; }stru_self_ptl_cfg_param; // 所有配置信息 @@ -269,7 +271,10 @@ typedef struct std::vector co_vec; std::vector dd_vec; + uint8_t ao_md5[16]; uint8_t param_md5[16]; + + std::vector ao_vec; std::vector param_vec; }stru_self_ptl_cfg; @@ -321,11 +326,11 @@ typedef struct float max; // 最大值 float step; // 步长 std::string unit; // 单位 - std::string default_value; // 默认值字符串 + // std::string default_value; // 默认值字符串 // void *p_default; // 默认值 }stru_signal_param; -typedef void (*signal_change_cb)(std::string saddr, SIGNAL_CTRL_STEP step, uint8_t data_type, void *p_data); +typedef void (*signal_change_cb)(std::string saddr, SIGNAL_CTRL_STEP step, uint8_t data_type, uint8_t setting_zone, void *p_data); @@ -335,16 +340,24 @@ int dc_signal_out(const std::string &saddr, const std::string &desc, uint8_t dat // 数据中心in信号注册并链接out信号接口 int dc_signal_in(const std::string &saddr, const std::string &desc, const std::string &link_saddr, uint8_t data_type, void **p_data); +int dc_signal_ao(const std::string &saddr, const std::string &desc, uint8_t data_type, const stru_signal_param ¶m, uint8_t ctrl_type, void *p_data, void *p_default_data, signal_change_cb cb); + +int dc_signal_ao_link_with_callback(const std::string &saddr, uint8_t data_type, void **p_data, signal_change_cb cb); + +int dc_signal_ao_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, void *p_data); + +int dc_signal_ao_set_val_without_check(const std::string &saddr, uint8_t data_type, void *p_data); + // 数据中心参数信号注册接口 -int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t data_type, const stru_signal_param ¶m, uint8_t ctrl_type, void *p_data, signal_change_cb cb); +int dc_signal_param(const std::string &saddr, 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, signal_change_cb cb); // 数据中心参数链接信号接口 -int dc_signal_param_link_with_callback(const std::string &saddr, uint8_t data_type, void **p_data, signal_change_cb cb); +int dc_signal_param_link_with_callback(const std::string &saddr, uint8_t data_type, std::vector &vec_p_data, signal_change_cb cb); // 数据中心参数设置接口 -int dc_signal_param_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, void *p_data); +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); -int dc_signal_param_set_val_without_check(const std::string &saddr, uint8_t data_type, void *p_data); +int dc_signal_param_set_val_without_check(const std::string &saddr, uint8_t data_type, uint8_t setting_zone, void *p_data); // 数据中心遥控信号注册接口 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); @@ -356,16 +369,18 @@ int dc_signal_yk_link_with_callback(const std::string &saddr, uint8_t data_type, int dc_signal_yk_set_status(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, void *p_data); // 数据中心获取out信号信息接口 -int dc_get_out_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, void **p_data); +int dc_get_out_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, std::vector &vec_p_data); // 数据中心获取in信号信息接口 -int dc_get_in_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, std::vector &vec_p_data); + +int dc_get_ao_siganl_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param ¶m, uint8_t &ctrl_type, std::vector &vec_p_data, std::vector &vec_p_default_data); // 数据中心获取参数信号信息接口 -int dc_get_param_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param ¶m, 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 ¶m, uint8_t &ctrl_type, std::vector &vec_p_data, std::vector &vec_p_default_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_get_yk_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, uint8_t &ctrl_type, std::vector &vec_p_data); // 数据中心获取信号值字符串接口 std::string dc_get_signal_val(void *p_data, uint8_t data_type); @@ -376,6 +391,8 @@ int dc_set_out_signal_val(const std::string &saddr, void *set_data); // 数据中心根据数据类型创建数据指针接口 void *dc_create_data_ptr_by_type(uint8_t data_type); +void dc_delete_signal_data(void *p_data, uint8_t data_type); + // 数据中心根据数据类型ID获取数据类型字符串接口 std::string dc_get_data_type_str_by_id(uint8_t data_type); diff --git a/src/protocol/libicp67/src/general_method.cpp b/src/protocol/libicp67/src/general_method.cpp index 9495348..24956dc 100644 --- a/src/protocol/libicp67/src/general_method.cpp +++ b/src/protocol/libicp67/src/general_method.cpp @@ -4,8 +4,8 @@ #include -LOCAL void icp67_param_get(stru_icp67 *p_icp67, stru_ti_1_2_data *p_data, uint16_t num); -LOCAL void icp67_param_set(stru_icp67 *p_icp67, uint8_t *p_data, uint16_t num); +LOCAL void icp67_ao_get(stru_icp67 *p_icp67, stru_ti_1_2_data *p_data, uint16_t num); +LOCAL void icp67_ao_set(stru_icp67 *p_icp67, uint8_t *p_data, uint16_t num); LOCAL void icp67_iec_point_tbl_get(stru_icp67 *p_icp67, uint16_t info_addr); LOCAL void icp67_time_set(stru_icp67 *p_icp67, stru_ti_5 *p_data); LOCAL void icp67_self_check_get(stru_icp67 *p_icp67); @@ -20,9 +20,9 @@ LOCAL void icp67_file_write_end_confirm(stru_icp67 *p_icp67, uint8_t result, uin LOCAL stru_genneral_method g_genneral_method = { - .param_get_cb = icp67_param_get, - .param_pop_out_cb = NULL, - .param_set_cb = icp67_param_set, + .ao_get_cb = icp67_ao_get, + .ao_pop_out_cb = NULL, + .ao_set_cb = icp67_ao_set, .iec_point_tbl_get_cb = icp67_iec_point_tbl_get, .iec_point_tbl_pop_out_cb = NULL, .time_set_cb = icp67_time_set, @@ -59,19 +59,19 @@ stru_genneral_method* icp67_get_genneral_method() return &g_genneral_method; } -void icp67_set_param_get_cb(icp67_param_get_cb *p_cb) +void icp67_set_ao_get_cb(icp67_ao_get_cb *p_cb) { - (*p_cb) = g_genneral_method.param_get_cb; + (*p_cb) = g_genneral_method.ao_get_cb; } -void icp67_set_param_pop_out_cb(icp67_param_pop_out_cb cb) +void icp67_set_ao_pop_out_cb(icp67_ao_pop_out_cb cb) { - g_genneral_method.param_pop_out_cb = cb; + g_genneral_method.ao_pop_out_cb = cb; } -void icp67_set_param_set_cb(icp67_param_set_cb *p_cb) +void icp67_set_ao_set_cb(icp67_ao_set_cb *p_cb) { - (*p_cb) = g_genneral_method.param_set_cb; + (*p_cb) = g_genneral_method.ao_set_cb; } void icp67_set_iec_point_tbl_get_cb(icp67_iec_point_tbl_get_cb *p_cb) @@ -206,11 +206,11 @@ void icp67_set_mx_change_cb(icp67_mx_change_cb cb) -LOCAL void icp67_param_get(stru_icp67 *p_icp67, stru_ti_1_2_data *p_data, uint16_t num) +LOCAL void icp67_ao_get(stru_icp67 *p_icp67, stru_ti_1_2_data *p_data, uint16_t num) { if(NULL == p_icp67 || NULL == p_data || num == 0) { - LOG_E("icp67_param_get: invalid input parameter\n"); + LOG_E("icp67_ao_get: invalid input parameter\n"); return; } @@ -240,11 +240,11 @@ LOCAL void icp67_param_get(stru_icp67 *p_icp67, stru_ti_1_2_data *p_data, uint16 } -LOCAL void icp67_param_set(stru_icp67 *p_icp67, uint8_t *p_data, uint16_t num) +LOCAL void icp67_ao_set(stru_icp67 *p_icp67, uint8_t *p_data, uint16_t num) { if(NULL == p_icp67 || NULL == p_data || num == 0) { - LOG_E("icp67_param_set: invalid input parameter\n"); + LOG_E("icp67_ao_set: invalid input parameter\n"); return; } diff --git a/src/protocol/libicp67/src/icp67.cpp b/src/protocol/libicp67/src/icp67.cpp index 5ac1c7f..a38a002 100644 --- a/src/protocol/libicp67/src/icp67.cpp +++ b/src/protocol/libicp67/src/icp67.cpp @@ -96,12 +96,12 @@ LOCAL int icp67_decode_ti_1(stru_icp67 *p_icp67, uint8_t *p_rx, uint16_t rx_len) uint16_t pos = 0; stru_genneral_method *p_genneral_method = icp67_get_genneral_method(); - for(uint8_t i = 0; p_genneral_method && p_genneral_method->param_pop_out_cb && i < p_asdu->num; i++) + for(uint8_t i = 0; p_genneral_method && p_genneral_method->ao_pop_out_cb && i < p_asdu->num; i++) { stru_ti_1_2_data_info *p_info = (stru_ti_1_2_data_info *)&p_asdu->data[pos]; pos += sizeof(stru_ti_1_2_data_info) + p_info->data_len; - p_genneral_method->param_pop_out_cb(p_icp67, p_info->data_addr, p_info->data_type, p_info->data_len, p_info->data); + p_genneral_method->ao_pop_out_cb(p_icp67, p_info->data_addr, p_info->data_type, p_info->data_len, p_info->data); } icp67_rtx_flag_set(p_icp67, ICP67_RX_FLAG, 0, 0); @@ -999,7 +999,7 @@ void icp67_init(stru_icp67 *p_icp67, icp67_send_cb send_cb, void *arg) p_icp67->tm_cnt = 0; } -int icp67_set_param_cfg_md5(stru_icp67 *p_icp67, uint8_t *p_md5) +int icp67_set_ao_cfg_md5(stru_icp67 *p_icp67, uint8_t *p_md5) { if(NULL == p_icp67 || NULL == p_md5) { diff --git a/src/protocol/libmms_m/inc/mms_m_parse_cfg.h b/src/protocol/libmms_m/inc/mms_m_parse_cfg.h index c48d219..db431d1 100644 --- a/src/protocol/libmms_m/inc/mms_m_parse_cfg.h +++ b/src/protocol/libmms_m/inc/mms_m_parse_cfg.h @@ -13,7 +13,9 @@ typedef struct { int quality; - void *p_val; + // void *p_val; + std::vector vec_p_val; + std::vector vec_p_default; stru_mms_m_time time; }stru_point_value; @@ -44,7 +46,9 @@ typedef struct float max_value; float step_value; std::string unit; - void *p_default; + + // std::vector vec_p_data; + // std::vector vec_p_default; }stru_point_item; typedef struct @@ -54,6 +58,7 @@ typedef struct std::vector mx; std::vector co; std::vector ao; + std::vector param; }stru_point_page; diff --git a/src/protocol/libmms_m/src/mms_m.cpp b/src/protocol/libmms_m/src/mms_m.cpp index 6a31ced..047ae9d 100644 --- a/src/protocol/libmms_m/src/mms_m.cpp +++ b/src/protocol/libmms_m/src/mms_m.cpp @@ -150,7 +150,7 @@ static void mms_m_show_MmsValue(MmsValue* mms_value) } -static int mms_m_get_mmsValue(MmsValue *mms_value, stru_point_item &item) +static int mms_m_get_mmsValue(MmsValue *mms_value, uint8_t &type, void *p_val) { if(NULL == mms_value) { @@ -163,29 +163,29 @@ static int mms_m_get_mmsValue(MmsValue *mms_value, stru_point_item &item) switch(mms_type) { case MMS_STRUCTURE: - return mms_m_get_mmsValue(MmsValue_getElement(mms_value, 0), item); + return mms_m_get_mmsValue(MmsValue_getElement(mms_value, 0), type, p_val); case MMS_BOOLEAN: - item.type = MMS_BOOLEAN; + type = MMS_BOOLEAN; // item.value.val.b = MmsValue_getBoolean(mms_value); - *(uint8_t *)item.value.p_val = MmsValue_getBoolean(mms_value); + *(uint8_t *)p_val = MmsValue_getBoolean(mms_value); break; case MMS_BIT_STRING: // LOG_I("MMS_BIT_STRING %s\r\n", MmsValue_toString(mms_value)); break; case MMS_INTEGER: - item.type = MMS_INTEGER; + type = MMS_INTEGER; // item.value.val.l = MmsValue_toInt32(mms_value); - *(int32_t *)item.value.p_val = MmsValue_toInt32(mms_value); + *(int32_t *)p_val = MmsValue_toInt32(mms_value); break; case MMS_UNSIGNED: - item.type = MMS_UNSIGNED; + type = MMS_UNSIGNED; // item.value.val.lu = MmsValue_toUint32(mms_value); - *(uint32_t *)item.value.p_val = MmsValue_toUint32(mms_value); + *(uint32_t *)p_val = MmsValue_toUint32(mms_value); break; case MMS_FLOAT: - item.type = MMS_FLOAT; + type = MMS_FLOAT; // item.value.val.f = MmsValue_toFloat(mms_value); - *(float *)item.value.p_val = MmsValue_toFloat(mms_value); + *(float *)p_val = MmsValue_toFloat(mms_value); break; default: LOG_E("mms_m_get_mmsValue Failed to read value (error code: %i)\n", MmsValue_getDataAccessError(mms_value)); @@ -390,7 +390,9 @@ static void mms_m_send_read_ao(stru_mms_m_obj &obj, stru_mms_m_event &event) mms_m_show_MmsValue(p_value); } - if(0 != mms_m_get_mmsValue(p_value, *p_item)) + void *p_val = event.set_zone >= p_item->value.vec_p_val.size() ? NULL : p_item->value.vec_p_val[event.set_zone]; + + if(0 != mms_m_get_mmsValue(p_value, p_item->type, p_val)) { LOG_E("get mms value failed"); MmsValue_delete(p_value); @@ -398,8 +400,8 @@ static void mms_m_send_read_ao(stru_mms_m_obj &obj, stru_mms_m_event &event) } mms_m_get_local_time(out_val.time); - out_val.p_value = it->value.p_val; - out_val.type = it->type; + out_val.p_value = p_val; + out_val.type = p_item->type; out_val.quality = 0; snprintf(out_val.name, sizeof(out_val.name) - 1, "%s", it->name.c_str()); @@ -689,7 +691,7 @@ static void mms_m_send_call_all(stru_mms_m_obj &obj) mms_m_show_MmsValue(p_value); } - if(0 != mms_m_get_mmsValue(p_value, *it)) + if(0 != mms_m_get_mmsValue(p_value, it->type, it->value.vec_p_val[0])) { LOG_E("get mms value failed"); MmsValue_delete(p_value); @@ -697,7 +699,7 @@ static void mms_m_send_call_all(stru_mms_m_obj &obj) } mms_m_get_local_time(out_val.time); - out_val.p_value = it->value.p_val; + out_val.p_value = it->value.vec_p_val[0]; out_val.type = it->type; out_val.quality = 0; @@ -801,6 +803,8 @@ static int mms_m_get_MmsValue(stru_point_value &point_value, stru_mms_m_out_valu } std::string temp_str; + void *p_val = point_value.vec_p_val[0]; + switch(MmsValue_getType(p_mms_values)) { case MMS_STRUCTURE: @@ -822,28 +826,28 @@ static int mms_m_get_MmsValue(stru_point_value &point_value, stru_mms_m_out_valu if (MmsValue_getBoolean(p_mms_values)) { // point_value.val.b = true; - *(uint8_t *)point_value.p_val = 1; + *(uint8_t *)p_val = 1; } else { // point_value.val.b = false; - *(uint8_t *)point_value.p_val = 0; + *(uint8_t *)p_val = 0; } break; case MMS_INTEGER: out_val.type = MMS_INTEGER; // point_value.val.l = MmsValue_toInt32(p_mms_values); - *(int32_t *)point_value.p_val = MmsValue_toInt32(p_mms_values); + *(int32_t *)p_val = MmsValue_toInt32(p_mms_values); break; case MMS_UNSIGNED: out_val.type = MMS_UNSIGNED; // point_value.val.lu = MmsValue_toUint32(p_mms_values); - *(uint32_t *)point_value.p_val = MmsValue_toUint32(p_mms_values); + *(uint32_t *)p_val = MmsValue_toUint32(p_mms_values); break; case MMS_FLOAT: out_val.type = MMS_FLOAT; // point_value.val.f = MmsValue_toFloat(p_mms_values); - *(float *)point_value.p_val = MmsValue_toFloat(p_mms_values); + *(float *)p_val = MmsValue_toFloat(p_mms_values); break; case MMS_BINARY_TIME: temp_str.clear(); @@ -924,7 +928,8 @@ static void mms_m_report_callback(void* parameter, ClientReport report) memset(&out_value, 0, sizeof(out_value)); memset(&point_value, 0, sizeof(point_value)); char temp[256] = {0}; - point_value.p_val = (void *)temp; + // point_value.p_val = (void *)temp; + point_value.vec_p_val.push_back((void *)temp); mms_m_get_MmsValue(point_value, out_value, mms_value, tm_flag, p_obj->debug_print_flag); @@ -934,7 +939,7 @@ static void mms_m_report_callback(void* parameter, ClientReport report) } out_value.reason = reason; - out_value.p_value = point_value.p_val; + out_value.p_value = point_value.vec_p_val[0]; out_value.app_fd = p_obj->obj_fd; out_value.time = point_value.time; @@ -1830,7 +1835,7 @@ int mms_m_out_get_signal_info(int app_fd, stru_mms_m_config *p_config) strncpy(sig.saddr, point.name.c_str(), sizeof(sig.saddr)); strncpy(sig.desc, point.desc.c_str(), sizeof(sig.desc)); sig.data_type = point.type; - sig.p_data = point.value.p_val; + sig.vec_p_data.push_back(point.value.vec_p_val[0]); } p_config->mx_num = obj.p_cfg->point.mx.size(); @@ -1851,7 +1856,7 @@ int mms_m_out_get_signal_info(int app_fd, stru_mms_m_config *p_config) strncpy(sig.saddr, point.name.c_str(), sizeof(sig.saddr)); strncpy(sig.desc, point.desc.c_str(), sizeof(sig.desc)); sig.data_type = point.type; - sig.p_data = point.value.p_val; + sig.vec_p_data.push_back(point.value.vec_p_val[0]); } p_config->co_num = obj.p_cfg->point.co.size(); @@ -1871,7 +1876,7 @@ int mms_m_out_get_signal_info(int app_fd, stru_mms_m_config *p_config) strncpy(co_sig.sig.saddr, point.name.c_str(), sizeof(co_sig.sig.saddr)); strncpy(co_sig.sig.desc, point.desc.c_str(), sizeof(co_sig.sig.desc)); co_sig.sig.data_type = point.type; - co_sig.sig.p_data = point.value.p_val; + co_sig.sig.vec_p_data.push_back(point.value.vec_p_val[0]); co_sig.ctrl_type = point.ctrl_model; } @@ -1892,7 +1897,8 @@ int mms_m_out_get_signal_info(int app_fd, stru_mms_m_config *p_config) strncpy(ao_sig.sig.saddr, point.name.c_str(), sizeof(ao_sig.sig.saddr)); strncpy(ao_sig.sig.desc, point.desc.c_str(), sizeof(ao_sig.sig.desc)); ao_sig.sig.data_type = point.type; - ao_sig.sig.p_data = point.value.p_val; + ao_sig.sig.vec_p_data.push_back(point.value.vec_p_val[0]); + ao_sig.vec_p_default.push_back(point.value.vec_p_default[0]); ao_sig.ctrl_type = point.ctrl_model; ao_sig.min = point.min_value; @@ -1901,6 +1907,39 @@ int mms_m_out_get_signal_info(int app_fd, stru_mms_m_config *p_config) strncpy(ao_sig.unit, point.unit.c_str(), sizeof(ao_sig.unit)); } + p_config->param_num = obj.p_cfg->point.param.size(); + p_config->p_param_sig = new stru_mms_m_param_signal[p_config->param_num]; + if(NULL == p_config->p_param_sig) + { + LOG_E("Failed to allocate memory for PARAM signal\n"); + p_config->param_num = 0; + return -1; + } + + for(int i = 0; i < p_config->param_num; i++) + { + stru_point_item &point = obj.p_cfg->point.param[i]; + stru_mms_m_param_signal ¶m_sig = p_config->p_param_sig[i]; + + strncpy(param_sig.sig.saddr, point.name.c_str(), sizeof(param_sig.sig.saddr)); + strncpy(param_sig.sig.desc, point.desc.c_str(), sizeof(param_sig.sig.desc)); + param_sig.sig.data_type = point.type; + + param_sig.ctrl_type = point.ctrl_model; + + param_sig.min = point.min_value; + param_sig.max = point.max_value; + param_sig.step = point.step_value; + strncpy(param_sig.unit, point.unit.c_str(), sizeof(param_sig.unit)); + + for(size_t j = 0; j < point.value.vec_p_val.size(); j++) + { + param_sig.sig.vec_p_data.push_back(point.value.vec_p_val[j]); + param_sig.vec_p_default.push_back(point.value.vec_p_default[j]); + } + } + + return 0; } @@ -2206,6 +2245,70 @@ int mms_m_get_data_value_str(void *data, uint8_t type, char *str) return 0; } +int mms_m_set_data_by_str(void *data, uint8_t type, const char *str) +{ + if(NULL == data || NULL == str) + { + LOG_E("Invalid data pointer, data %p, str %p\n", data, str); + return -1; + } + + switch(type) + { + case _MMS_M_data_type_bool: + if(0 == strcasecmp(str, "true") || 0 == strcmp(str, "1")) + { + *(uint8_t *)data = 1; + } + else if(0 == strcasecmp(str, "false") || 0 == strcmp(str, "0")) + { + *(uint8_t *)data = 0; + } + else + { + LOG_E("Invalid boolean string: %s\n", str); + return -1; + } + break; + case _MMS_M_data_type_int8: + *(int8_t *)data = (int8_t)atoi(str); + break; + case _MMS_M_data_type_int16: + *(int16_t *)data = (int16_t)atoi(str); + break; + case _MMS_M_data_type_int32: + *(int32_t *)data = (int32_t)atoi(str); + break; + case _MMS_M_data_type_int64: + *(int64_t *)data = (int64_t)atol(str); + break; + case _MMS_M_data_type_uint8: + *(uint8_t *)data = (uint8_t)atoi(str); + break; + case _MMS_M_data_type_uint16: + *(uint16_t *)data = (uint16_t)atoi(str); + break; + case _MMS_M_data_type_uint32: + *(uint32_t *)data = (uint32_t)atoi(str); + break; + case _MMS_M_data_type_uint64: + *(uint64_t *)data = (uint64_t)atol(str); + break; + case _MMS_M_data_type_float: + *(float *)data = (float)atof(str); + break; + case _MMS_M_data_type_double: + *(double *)data = atof(str); + break; + case _MMS_M_data_type_string: + strncpy((char *)data, str, MMS_M_STR_LEN); + break; + default: + return -1; + } + + return 0; +} static struct _mms_m_resaon_str { ReasonForInclusion reason; diff --git a/src/protocol/libmms_m/src/mms_m_parse_cfg.cpp b/src/protocol/libmms_m/src/mms_m_parse_cfg.cpp index 8e07d8b..3d4d48c 100644 --- a/src/protocol/libmms_m/src/mms_m_parse_cfg.cpp +++ b/src/protocol/libmms_m/src/mms_m_parse_cfg.cpp @@ -10,7 +10,10 @@ static const char *ELE_St = "St"; static const char *ELE_Mx = "Mx"; static const char *ELE_Co = "Co"; static const char *ELE_Ao = "Ao"; +static const char *ELE_Param = "Param"; static const char *ELE_Item = "Item"; +static const char *ELE_SubItem = "SubItem"; + static const char *KEY_NO = "no"; static const char *KEY_NAME = "name"; @@ -28,6 +31,8 @@ static const char *KEY_MIN_VAL = "minVal"; static const char *KEY_MAX_VAL = "maxVal"; static const char *KEY_STEP_VAL = "stepVal"; static const char *KEY_UNIT = "unit"; + +static const char *KEY_VAL = "val"; static const char *KEY_DEFAULT_VAL = "default"; @@ -169,18 +174,9 @@ void parse_cfg_item(tinyxml2::XMLElement *item, std::vector &it item_list.back().set_value = NULL; item_list.back().control = NULL; - stru_point_item *p_item = &item_list.back(); + // stru_point_item *p_item = &item_list.back(); - if(NULL != (str = item->Attribute(KEY_DEFAULT_VAL))) - { - p_item->p_default = mms_m_create_data_ptr(p_item->type); - if(NULL != p_item->p_default) - { - mms_m_set_data_value(p_item->p_default, (void *)str, p_item->type); - } - } - - p_item->value.p_val = mms_m_create_data_ptr(p_item->type); + // p_item->value.p_val = mms_m_create_data_ptr(p_item->type); } @@ -244,13 +240,15 @@ static int parse_cfg_point(tinyxml2::XMLElement *point, stru_point_page &point_p return -1; } - tinyxml2::XMLElement *st, *mx, *co, *ao, *item; + tinyxml2::XMLElement *st, *mx, *co, *ao, *param, *item = NULL, *sub_item = NULL; if(NULL != (st = point->FirstChildElement(ELE_St))) { for(item = st->FirstChildElement(ELE_Item); item; item = item->NextSiblingElement(ELE_Item)) { parse_cfg_item(item, point_page.st, ied); + + point_page.st.back().value.vec_p_val.push_back(mms_m_create_data_ptr(point_page.st.back().type)); } } @@ -259,6 +257,8 @@ static int parse_cfg_point(tinyxml2::XMLElement *point, stru_point_page &point_p for(item = mx->FirstChildElement(ELE_Item); item; item = item->NextSiblingElement(ELE_Item)) { parse_cfg_item(item, point_page.mx, ied); + + point_page.mx.back().value.vec_p_val.push_back(mms_m_create_data_ptr(point_page.mx.back().type)); } } @@ -267,6 +267,8 @@ static int parse_cfg_point(tinyxml2::XMLElement *point, stru_point_page &point_p for(item = co->FirstChildElement(ELE_Item); item; item = item->NextSiblingElement(ELE_Item)) { parse_cfg_item(item, point_page.co, ied); + + point_page.co.back().value.vec_p_val.push_back(mms_m_create_data_ptr(point_page.co.back().type)); } } @@ -275,6 +277,40 @@ static int parse_cfg_point(tinyxml2::XMLElement *point, stru_point_page &point_p for(item = ao->FirstChildElement(ELE_Item); item; item = item->NextSiblingElement(ELE_Item)) { parse_cfg_item(item, point_page.ao, ied); + + point_page.ao.back().value.vec_p_val.push_back(mms_m_create_data_ptr(point_page.ao.back().type)); + point_page.ao.back().value.vec_p_default.push_back(mms_m_create_data_ptr(point_page.ao.back().type)); + } + } + + if(NULL != (param = point->FirstChildElement(ELE_Param))) + { + for(item = param->FirstChildElement(ELE_Item); item; item = item->NextSiblingElement(ELE_Item)) + { + parse_cfg_item(item, point_page.param, ied); + + for(sub_item = item->FirstChildElement(ELE_SubItem); sub_item; sub_item = sub_item->NextSiblingElement(ELE_SubItem)) + { + const char *val = sub_item->Attribute(KEY_VAL); + const char *def = sub_item->Attribute(KEY_DEFAULT_VAL); + + void *p_val = mms_m_create_data_ptr(point_page.param.back().type); + void *p_def = mms_m_create_data_ptr(point_page.param.back().type); + + if(NULL != val) + { + mms_m_set_data_by_str(p_val, point_page.param.back().type, val); + } + + if(NULL != def) + { + mms_m_set_data_by_str(p_def, point_page.param.back().type, def); + } + + point_page.param.back().value.vec_p_default.push_back(p_def); + point_page.param.back().value.vec_p_val.push_back(p_val); + + } } } diff --git a/src/system/RTU/src/self_ptl_cfg.cpp b/src/system/RTU/src/self_ptl_cfg.cpp index 50fd6b2..8d3b1a1 100644 --- a/src/system/RTU/src/self_ptl_cfg.cpp +++ b/src/system/RTU/src/self_ptl_cfg.cpp @@ -8,9 +8,12 @@ LOCAL const char *ele_St = "St"; LOCAL const char *ele_Mx = "Mx"; LOCAL const char *ele_Co = "Co"; LOCAL const char *ele_Dd = "Dd"; +LOCAL const char *ele_Ao = "Ao"; LOCAL const char *ele_Param = "Param"; +LOCAL const char *ele_Signal = "Signal"; LOCAL const char *ele_Item = "Item"; +// LOCAL const char *ele_SubItem = "SubItem"; LOCAL const char *attr_count = "count"; LOCAL const char *attr_md5 = "md5"; @@ -19,13 +22,14 @@ LOCAL const char *attr_saddr = "saddr"; LOCAL const char *attr_desc = "desc"; LOCAL const char *attr_inf = "inf"; LOCAL const char *attr_type = "type"; -LOCAL const char *attr_default = "default"; LOCAL const char *attr_unit = "unit"; LOCAL const char *attr_min = "min"; LOCAL const char *attr_max = "max"; LOCAL const char *attr_step = "step"; +LOCAL const char *attr_num = "num"; - +LOCAL const char *attr_value = "value"; +LOCAL const char *attr_default = "default"; LOCAL stru_self_ptl_cfg g_self_ptl_cfg = {.init = false}; @@ -84,14 +88,14 @@ LOCAL int parse_base(tinyxml2::XMLElement *root) continue; } - tinyxml2::XMLElement *item_ele = parent_ele->FirstChildElement(ele_Item); - while (item_ele != nullptr) + tinyxml2::XMLElement *signal_ele = parent_ele->FirstChildElement(ele_Signal); + while (signal_ele != nullptr) { stru_self_ptl_cfg_base cfg_base; - const char *saddr = item_ele->Attribute(attr_saddr); - const char *desc = item_ele->Attribute(attr_desc); + const char *saddr = signal_ele->Attribute(attr_saddr); + const char *desc = signal_ele->Attribute(attr_desc); int inf = 0; - if(tinyxml2::XMLError::XML_SUCCESS != item_ele->QueryIntAttribute(attr_inf, &inf)) + if(tinyxml2::XMLError::XML_SUCCESS != signal_ele->QueryIntAttribute(attr_inf, &inf)) { MY_LOG_E("failed to parse attribute %s in element %s, inf get failed", attr_inf, local_parse.type.c_str()); continue; @@ -108,8 +112,7 @@ LOCAL int parse_base(tinyxml2::XMLElement *root) cfg_base.inf = inf; local_parse.p_vec->push_back(cfg_base); - - item_ele = item_ele->NextSiblingElement(ele_Item); + signal_ele = signal_ele->NextSiblingElement(ele_Signal); } if(local_parse.p_vec->size() != count) @@ -123,6 +126,96 @@ LOCAL int parse_base(tinyxml2::XMLElement *root) return 0; } +int parse_ao(tinyxml2::XMLElement *root) +{ + tinyxml2::XMLElement *parent_ele = root->FirstChildElement(ele_Ao); + if (parent_ele == nullptr) + { + MY_LOG_E("not found element %s", ele_Ao); + return -1; + } + + const char *count_str = parent_ele->Attribute(attr_count); + int count = 0; + if (count_str != nullptr) + { + count = atoi(count_str); + } + else + { + MY_LOG_E("not found attribute %s in element %s", attr_count, ele_Ao); + return -1; + } + + const char *md5_str = parent_ele->Attribute(attr_md5); + if(nullptr == md5_str) + { + MY_LOG_E("not found attribute %s in element %s", attr_md5, ele_Ao); + return -1; + } + else + { + if(strlen(md5_str) != 32) + { + MY_LOG_E("invalid md5 string %s in element %s", md5_str, ele_Ao); + return -1; + } + for(int i = 0; i < 16; i++) + { + std::string byte_str = md5_str + i*2; + byte_str[2] = '\0'; + g_self_ptl_cfg.ao_md5[i] = (uint8_t)strtoul(byte_str.c_str(), nullptr, 16); + } + } + + tinyxml2::XMLElement *signal_ele = parent_ele->FirstChildElement(ele_Signal); + while(nullptr != signal_ele) + { + stru_self_ptl_cfg_param cfg_ao; + const char *saddr = signal_ele->Attribute(attr_saddr); + const char *desc = signal_ele->Attribute(attr_desc); + int inf = 0; + if(tinyxml2::XMLError::XML_SUCCESS != signal_ele->QueryIntAttribute(attr_inf, &inf)) + { + MY_LOG_E("failed to parse attribute %s in element %s, inf get failed", attr_inf, ele_Ao); + continue; + } + const char *type = signal_ele->Attribute(attr_type); + const char *unit = signal_ele->Attribute(attr_unit); + const char *min = signal_ele->Attribute(attr_min); + const char *max = signal_ele->Attribute(attr_max); + const char *step = signal_ele->Attribute(attr_step); + const char *value = signal_ele->Attribute(attr_value); + const char *default_value = signal_ele->Attribute(attr_default); + + cfg_ao.base.saddr = saddr == nullptr ? "" : saddr; + cfg_ao.base.desc = desc == nullptr ? "" : desc; + cfg_ao.base.inf = inf; + cfg_ao.type = dc_get_data_type_id_by_str(type == nullptr ? "" : type); + cfg_ao.unit = unit == nullptr ? "" : unit; + cfg_ao.min = min == nullptr ? "" : min; + cfg_ao.max = max == nullptr ? "" : max; + cfg_ao.step = step == nullptr ? "" : step; + + + cfg_ao.val.push_back(value == nullptr ? "" : value); + cfg_ao.default_value.push_back(default_value == nullptr ? "" : default_value); + + g_self_ptl_cfg.ao_vec.push_back(cfg_ao); + + if(inf == 0 && cfg_ao.type == DATA_TYPE_C64) + { + MY_LOG_I("saddr %s, desc %s", cfg_ao.base.saddr.c_str(), cfg_ao.base.desc.c_str()); + } + + signal_ele = signal_ele->NextSiblingElement(ele_Signal); + } + + MY_LOG_I("ao signals: %d", (int)g_self_ptl_cfg.ao_vec.size()); + + return 0; +} + int parse_param(tinyxml2::XMLElement *root) { tinyxml2::XMLElement *parent_ele = root->FirstChildElement(ele_Param); @@ -165,30 +258,30 @@ int parse_param(tinyxml2::XMLElement *root) } } - tinyxml2::XMLElement *item_ele = parent_ele->FirstChildElement(ele_Item); - while (item_ele != nullptr) + tinyxml2::XMLElement *signal_ele = parent_ele->FirstChildElement(ele_Signal); + while (signal_ele != nullptr) { stru_self_ptl_cfg_param cfg_param; - const char *saddr = item_ele->Attribute(attr_saddr); - const char *desc = item_ele->Attribute(attr_desc); + const char *saddr = signal_ele->Attribute(attr_saddr); + const char *desc = signal_ele->Attribute(attr_desc); int inf = 0; - if(tinyxml2::XMLError::XML_SUCCESS != item_ele->QueryIntAttribute(attr_inf, &inf)) + if(tinyxml2::XMLError::XML_SUCCESS != signal_ele->QueryIntAttribute(attr_inf, &inf)) { MY_LOG_E("failed to parse attribute %s in element %s, inf get failed", attr_inf, ele_Param); continue; } - const char *type = item_ele->Attribute(attr_type); - const char *default_value = item_ele->Attribute(attr_default); - const char *unit = item_ele->Attribute(attr_unit); - const char *min = item_ele->Attribute(attr_min); - const char *max = item_ele->Attribute(attr_max); - const char *step = item_ele->Attribute(attr_step); + const char *type = signal_ele->Attribute(attr_type); + const char *unit = signal_ele->Attribute(attr_unit); + const char *min = signal_ele->Attribute(attr_min); + const char *max = signal_ele->Attribute(attr_max); + const char *step = signal_ele->Attribute(attr_step); + const char *num = signal_ele->Attribute(attr_num); cfg_param.base.saddr = saddr != nullptr ? saddr : ""; cfg_param.base.desc = desc != nullptr ? desc : ""; cfg_param.base.inf = inf; cfg_param.type = dc_get_data_type_id_by_str(type != nullptr ? type : ""); - cfg_param.default_value = default_value != nullptr ? default_value : ""; + cfg_param.num = num != nullptr ? atoi(num) : 0; cfg_param.unit = unit != nullptr ? unit : ""; cfg_param.min = min != nullptr ? min : ""; cfg_param.max = max != nullptr ? max : ""; @@ -196,13 +289,29 @@ int parse_param(tinyxml2::XMLElement *root) g_self_ptl_cfg.param_vec.push_back(cfg_param); - item_ele = item_ele->NextSiblingElement(ele_Item); + tinyxml2::XMLElement *item_ele = signal_ele->FirstChildElement(ele_Item); + while(item_ele != nullptr) + { + const char *val = item_ele->Attribute(attr_value); + const char *default_val = item_ele->Attribute(attr_default); + if(val != nullptr) + { + g_self_ptl_cfg.param_vec.back().val.push_back(val); + } + if(default_val != nullptr) + { + g_self_ptl_cfg.param_vec.back().default_value.push_back(default_val); + } + item_ele = item_ele->NextSiblingElement(ele_Item); + } + + signal_ele = signal_ele->NextSiblingElement(ele_Signal); } if(g_self_ptl_cfg.param_vec.size() != count) { MY_LOG_E("count mismatch for element %s, expected %d, actual %d", - ele_Param, count, (int)g_self_ptl_cfg.param_vec.size()); + ele_Signal, count, (int)g_self_ptl_cfg.param_vec.size()); return -1; } @@ -239,6 +348,12 @@ int self_ptl_cfg_parse(const std::string &path) return -1; } + if(parse_ao(root) != 0) + { + MY_LOG_E("Failed to parse ao elements"); + return -1; + } + // 解析param if(parse_param(root) != 0) { diff --git a/src/system/libdatacenter/inc/dc_param.h b/src/system/libdatacenter/inc/dc_param.h index d16caf0..7986e5a 100644 --- a/src/system/libdatacenter/inc/dc_param.h +++ b/src/system/libdatacenter/inc/dc_param.h @@ -4,3 +4,6 @@ #include "mySystem.h" #include "dc_signal.h" +#define DC_PARAM_PATH "/mnt/RTU/test/file/PARAM/param.xml" + +void dc_param_cfg_parse(); \ No newline at end of file diff --git a/src/system/libdatacenter/inc/dc_signal.h b/src/system/libdatacenter/inc/dc_signal.h index dabd723..1dee3c6 100644 --- a/src/system/libdatacenter/inc/dc_signal.h +++ b/src/system/libdatacenter/inc/dc_signal.h @@ -15,7 +15,9 @@ typedef struct stru_signal std::string saddr; // 短地址 std::string desc; // 描述 uint8_t data_type; // 数据类型 - void *p_data; // 数据指针 + // void *p_data; // 数据指针 + std::vector vec_p_data; // 数据指针列表(支持多条目) + std::vector vec_p_default_data; // 默认值指针列表(支持多条目) std::vector link_saddrs; // stru_signal_ctrl ctrl; // 信号扩展信息 uint8_t ctrl_type; // 信号控制类型 @@ -24,6 +26,29 @@ typedef struct stru_signal }stru_signal; +// 参数分组信息(用于XML序列化) +typedef struct +{ + std::string saddr; + std::string desc; + uint8_t data_type; + int num; + float min, max, step; + std::string unit; + + std::vector val; + std::vector default_val; +} dc_param_group_info; + +void dc_param_group_add(const dc_param_group_info &group); +std::vector dc_param_group_get_all(); +void dc_param_group_clear(); + +void dc_set_signal_val_from_str(void *p_data, uint8_t data_type, const std::string &str); +bool dc_get_param_cfg_change(); +void dc_set_param_cfg_change(bool change); + +void dc_param_cfg_check(); diff --git a/src/system/libdatacenter/src/datacenter.cpp b/src/system/libdatacenter/src/datacenter.cpp index 78a3aeb..bbbe923 100644 --- a/src/system/libdatacenter/src/datacenter.cpp +++ b/src/system/libdatacenter/src/datacenter.cpp @@ -1,5 +1,7 @@ #include "mySystem.h" #include "myLog.h" + +#include "dc_param.h" #include "dc_signal.h" @@ -8,6 +10,8 @@ int app_datacenter_init1(void *arg) { + dc_param_cfg_parse(); + return 0; } @@ -53,6 +57,7 @@ void *app_datacenter(void *arg) if(event & EV_TIMER3) { + dc_param_cfg_check(); p_app->run_cnt++; } } diff --git a/src/system/libdatacenter/src/dc_param.cpp b/src/system/libdatacenter/src/dc_param.cpp index bb83b1f..164f202 100644 --- a/src/system/libdatacenter/src/dc_param.cpp +++ b/src/system/libdatacenter/src/dc_param.cpp @@ -1,3 +1,311 @@ #include "dc_param.h" +#include "tinyxml2.h" -LOCAL const char* DC_PARAM_PATH = "/mnt/RTU/test/file/PRAM/param.xml"; \ No newline at end of file +void dc_param_cfg_parse() +{ + using namespace tinyxml2; + + XMLDocument doc; + if (XML_SUCCESS != doc.LoadFile(DC_PARAM_PATH)) + { + MY_LOG_E("failed to load param file: %s", DC_PARAM_PATH); + return; + } + + dc_param_group_clear(); + + XMLElement *root = doc.RootElement(); + if (nullptr == root) + { + MY_LOG_E("param file has no root element"); + return; + } + + // 解析 Ao 段:单值参数(一份值 + 一份缺省值) + XMLElement *ao_elem = root->FirstChildElement("Ao"); + if (ao_elem) + { + for (XMLElement *sig = ao_elem->FirstChildElement("Signal"); sig != nullptr; + sig = sig->NextSiblingElement("Signal")) + { + const char *saddr = sig->Attribute("saddr"); + const char *desc = sig->Attribute("desc"); + const char *type_str = sig->Attribute("type"); + if (nullptr == saddr || nullptr == desc || nullptr == type_str) + { + MY_LOG_E("Ao Signal missing required attributes, skipping"); + continue; + } + + uint8_t data_type = dc_get_data_type_id_by_str(type_str); + if (0 == data_type) + { + MY_LOG_E("unknown data type %s for saddr %s", type_str, saddr); + continue; + } + + float min = sig->FloatAttribute("min", 0.0f); + float max = sig->FloatAttribute("max", 0.0f); + float step = sig->FloatAttribute("step", 0.0f); + const char *unit = sig->Attribute("unit"); + + dc_param_group_info group; + group.saddr = std::string(saddr); + group.desc = std::string(desc); + group.data_type = data_type; + group.min = min; + group.max = max; + group.step = step; + group.unit = unit ? std::string(unit) : std::string(); + group.num = -1; + + std::vector vec_p_data; + std::vector vec_p_default_data; + + // Ao 段:从 Signal 属性读取单值 + const char *val = sig->Attribute("value"); + const char *default_val = sig->Attribute("default"); + + void *p_data = dc_create_data_ptr_by_type(data_type); + if (p_data) + { + if (val && strlen(val) > 0) + dc_set_signal_val_from_str(p_data, data_type, std::string(val)); + else if (default_val && strlen(default_val) > 0) + dc_set_signal_val_from_str(p_data, data_type, std::string(default_val)); + vec_p_data.push_back(p_data); + } + + void *p_default_data = dc_create_data_ptr_by_type(data_type); + if (p_default_data) + { + if (default_val && strlen(default_val) > 0) + dc_set_signal_val_from_str(p_default_data, data_type, std::string(default_val)); + vec_p_default_data.push_back(p_default_data); + } + + if (!vec_p_data.empty()) + { + stru_signal_param param; + param.min = group.min; + param.max = group.max; + param.step = group.step; + param.unit = group.unit; + + dc_signal_param(group.saddr, group.desc, group.data_type, param, + SIGNAL_CTRL_TYPE::SBO_NORMAL, + vec_p_data, vec_p_default_data, nullptr); + } + + dc_param_group_add(group); + } + } + + // 解析 Param 段:多值参数(多份值 + 多份缺省值) + XMLElement *param_elem = root->FirstChildElement("Param"); + if (param_elem) + { + for (XMLElement *sig = param_elem->FirstChildElement("Signal"); sig != nullptr; + sig = sig->NextSiblingElement("Signal")) + { + const char *saddr = sig->Attribute("saddr"); + const char *desc = sig->Attribute("desc"); + const char *type_str = sig->Attribute("type"); + if (nullptr == saddr || nullptr == desc || nullptr == type_str) + { + MY_LOG_E("Param Signal missing required attributes, skipping"); + continue; + } + + uint8_t data_type = dc_get_data_type_id_by_str(type_str); + if (0 == data_type) + { + MY_LOG_E("unknown data type %s for saddr %s", type_str, saddr); + continue; + } + + float min = sig->FloatAttribute("min", 0.0f); + float max = sig->FloatAttribute("max", 0.0f); + float step = sig->FloatAttribute("step", 0.0f); + const char *unit = sig->Attribute("unit"); + + dc_param_group_info group; + group.saddr = std::string(saddr); + group.desc = std::string(desc); + group.data_type = data_type; + group.min = min; + group.max = max; + group.step = step; + group.unit = unit ? std::string(unit) : std::string(); + + std::vector vec_p_data; + std::vector vec_p_default_data; + + int num = sig->IntAttribute("num", -1); + if (num >= 1) + { + int item_count = 0; + for (XMLElement *item = sig->FirstChildElement("Item"); item != nullptr; + item = item->NextSiblingElement("Item")) + { + const char *val = item->Attribute("value"); + const char *default_val = item->Attribute("default"); + + void *p_data = dc_create_data_ptr_by_type(data_type); + if (p_data) + { + if (val && strlen(val) > 0) + dc_set_signal_val_from_str(p_data, data_type, std::string(val)); + else if (default_val && strlen(default_val) > 0) + dc_set_signal_val_from_str(p_data, data_type, std::string(default_val)); + vec_p_data.push_back(p_data); + } + + void *p_default_data = dc_create_data_ptr_by_type(data_type); + if (p_default_data) + { + if (default_val && strlen(default_val) > 0) + dc_set_signal_val_from_str(p_default_data, data_type, std::string(default_val)); + vec_p_default_data.push_back(p_default_data); + } + + item_count++; + } + group.num = item_count; + } + else + { + group.num = -1; + } + + if (!vec_p_data.empty()) + { + stru_signal_param param; + param.min = group.min; + param.max = group.max; + param.step = group.step; + param.unit = group.unit; + + dc_signal_param(group.saddr, group.desc, group.data_type, param, + SIGNAL_CTRL_TYPE::SBO_NORMAL, + vec_p_data, vec_p_default_data, nullptr); + } + + dc_param_group_add(group); + } + } + + // 兼容旧格式:Signal 直接作为 root 子元素(无 Ao/Param 分组) + if (!ao_elem && !param_elem) + { + for (XMLElement *sig = root->FirstChildElement("Signal"); sig != nullptr; + sig = sig->NextSiblingElement("Signal")) + { + const char *saddr = sig->Attribute("saddr"); + const char *desc = sig->Attribute("desc"); + const char *type_str = sig->Attribute("type"); + if (nullptr == saddr || nullptr == desc || nullptr == type_str) + { + MY_LOG_E("Signal missing required attributes, skipping"); + continue; + } + + uint8_t data_type = dc_get_data_type_id_by_str(type_str); + if (0 == data_type) + { + MY_LOG_E("unknown data type %s for saddr %s", type_str, saddr); + continue; + } + + float min = sig->FloatAttribute("min", 0.0f); + float max = sig->FloatAttribute("max", 0.0f); + float step = sig->FloatAttribute("step", 0.0f); + const char *unit = sig->Attribute("unit"); + + dc_param_group_info group; + group.saddr = std::string(saddr); + group.desc = std::string(desc); + group.data_type = data_type; + group.min = min; + group.max = max; + group.step = step; + group.unit = unit ? std::string(unit) : std::string(); + + std::vector vec_p_data; + std::vector vec_p_default_data; + + int num = sig->IntAttribute("num", -1); + if (num >= 1) + { + int item_count = 0; + for (XMLElement *item = sig->FirstChildElement("Item"); item != nullptr; + item = item->NextSiblingElement("Item")) + { + const char *val = item->Attribute("value"); + const char *default_val = item->Attribute("default"); + + void *p_data = dc_create_data_ptr_by_type(data_type); + if (p_data) + { + if (val && strlen(val) > 0) + dc_set_signal_val_from_str(p_data, data_type, std::string(val)); + else if (default_val && strlen(default_val) > 0) + dc_set_signal_val_from_str(p_data, data_type, std::string(default_val)); + vec_p_data.push_back(p_data); + } + + void *p_default_data = dc_create_data_ptr_by_type(data_type); + if (p_default_data) + { + if (default_val && strlen(default_val) > 0) + dc_set_signal_val_from_str(p_default_data, data_type, std::string(default_val)); + vec_p_default_data.push_back(p_default_data); + } + + item_count++; + } + group.num = item_count; + } + else + { + group.num = -1; + + const char *val = sig->Attribute("value"); + const char *default_val = sig->Attribute("default"); + + void *p_data = dc_create_data_ptr_by_type(data_type); + if (p_data) + { + if (val && strlen(val) > 0) + dc_set_signal_val_from_str(p_data, data_type, std::string(val)); + else if (default_val && strlen(default_val) > 0) + dc_set_signal_val_from_str(p_data, data_type, std::string(default_val)); + vec_p_data.push_back(p_data); + } + + void *p_default_data = dc_create_data_ptr_by_type(data_type); + if (p_default_data) + { + if (default_val && strlen(default_val) > 0) + dc_set_signal_val_from_str(p_default_data, data_type, std::string(default_val)); + vec_p_default_data.push_back(p_default_data); + } + } + + if (!vec_p_data.empty()) + { + stru_signal_param param; + param.min = group.min; + param.max = group.max; + param.step = group.step; + param.unit = group.unit; + + dc_signal_param(group.saddr, group.desc, group.data_type, param, + SIGNAL_CTRL_TYPE::SBO_NORMAL, + vec_p_data, vec_p_default_data, nullptr); + } + + dc_param_group_add(group); + } + } +} diff --git a/src/system/libdatacenter/src/dc_siganl.cpp b/src/system/libdatacenter/src/dc_siganl.cpp index 1e75405..31360d7 100644 --- a/src/system/libdatacenter/src/dc_siganl.cpp +++ b/src/system/libdatacenter/src/dc_siganl.cpp @@ -6,10 +6,13 @@ #include #include "dc_signal.h" +#include "dc_param.h" #include "myLog.h" #include "mySystem.h" #include "myCmd.h" +#include "tinyxml2.h" + struct XXH128Hash { size_t operator()(const XXH128_hash_t& h) const noexcept { // 低版本库无XXH3_64bits_fromCanonical,手动混合高低64位生成哈希 @@ -50,20 +53,44 @@ typedef struct { stru_signal_map signal_out; stru_signal_map signal_in; - stru_signal_map siganl_yk; - stru_signal_map siganl_param; + 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; + +LOCAL std::vector g_param_groups; +LOCAL std::mutex g_param_groups_mutex; + 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 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); -int dc_get_out_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, void **p_data) + +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, std::vector &vec_p_data) { stru_signal *p_signal = dc_find_out_signal(saddr); if(p_signal == nullptr) @@ -74,12 +101,25 @@ int dc_get_out_signal_info(const std::string &saddr, std::string &desc, uint8_t desc = p_signal->desc; data_type = p_signal->data_type; - (*p_data) = p_signal->p_data; + + 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; + } + + vec_p_data.push_back(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) +int dc_get_in_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, std::vector &vec_p_data) { stru_signal *p_signal = dc_find_in_signal(saddr); if(p_signal == nullptr) @@ -90,14 +130,61 @@ int dc_get_in_signal_info(const std::string &saddr, std::string &desc, uint8_t & desc = p_signal->desc; data_type = p_signal->data_type; - (*p_data) = p_signal->p_data; + + if(!p_signal->vec_p_data.empty() && nullptr != p_signal->vec_p_data[0]) + { + vec_p_data.push_back(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_siganl_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param ¶m, uint8_t &ctrl_type, std::vector &vec_p_data, std::vector &vec_p_default_data) +{ + stru_signal *p_signal = dc_find_signal(XXH3_128bits(saddr.c_str(), saddr.length()), 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; + param.min = p_signal->param.min; + param.max = p_signal->param.max; + param.step = p_signal->param.step; + 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]) + { + vec_p_data.push_back(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; + } + + if(!p_signal->vec_p_default_data.empty() && nullptr != p_signal->vec_p_default_data[0]) + { + vec_p_default_data.push_back(p_signal->vec_p_default_data[0]); + } + else + { + MY_LOG_E("saddr %s vec_p_default_data is empty or vec_p_default_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 ¶m, 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 ¶m, uint8_t &ctrl_type, std::vector &vec_p_data, std::vector &vec_p_default_data) { - stru_signal *p_signal = dc_find_signal(XXH3_128bits(saddr.c_str(), saddr.length()), g_datacenter.siganl_param); + stru_signal *p_signal = dc_find_signal(XXH3_128bits(saddr.c_str(), saddr.length()), g_datacenter.signal_param); if(p_signal == nullptr) { MY_LOG_E("saddr %s not found", saddr.c_str()); @@ -109,16 +196,36 @@ int dc_get_param_signal_info(const std::string &saddr, std::string &desc, uint8_ param.max = p_signal->param.max; param.step = p_signal->param.step; param.unit = p_signal->param.unit; - param.default_value = p_signal->param.default_value; ctrl_type = p_signal->ctrl_type; - (*p_data) = p_signal->p_data; + + 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; + } + + vec_p_data.push_back(&p_signal->vec_p_data[i]); + } + + for(size_t i = 0; i < p_signal->vec_p_default_data.size(); i++) + { + if(nullptr == p_signal->vec_p_default_data[i]) + { + MY_LOG_E("saddr %s vec_p_default_data[%ld] is nullptr", saddr.c_str(), i); + return -1; + } + + vec_p_default_data.push_back(&p_signal->vec_p_default_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) +int dc_get_yk_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, uint8_t &ctrl_type, std::vector &vec_p_data) { - stru_signal *p_signal = dc_find_signal(XXH3_128bits(saddr.c_str(), saddr.length()), g_datacenter.siganl_yk); + stru_signal *p_signal = dc_find_signal(XXH3_128bits(saddr.c_str(), saddr.length()), g_datacenter.signal_yk); if(p_signal == nullptr) { MY_LOG_E("saddr %s not found", saddr.c_str()); @@ -127,143 +234,12 @@ int dc_get_yk_signal_info(const std::string &saddr, std::string &desc, uint8_t & desc = p_signal->desc; data_type = p_signal->data_type; ctrl_type = p_signal->ctrl_type; - (*p_data) = p_signal->p_data; + vec_p_data.push_back(&p_signal->vec_p_data[0]); return 0; } - -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) - { - *exist_signal = signal; - return 0; - } - } - - stru_signal new_signal = signal; - conflict_it->second.push_back(&new_signal); - } - 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); - conficts.push_back(&signal); - dc_signal_map.hash_conflict_table[signal.hash] = conficts; - } - else - { - map_it->second = signal; - } - } - else - { - signal_map.emplace(signal.hash, signal); - } - } - - dc_update_global_index(signal, dc_signal_map); - - return 0; -} - - -int dc_signal_out(const std::string &saddr, const std::string &desc, uint8_t data_type, void *p_data) -{ - 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.p_data = p_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_in(const std::string &saddr, const std::string &desc, const std::string &link_saddr, uint8_t data_type, void **p_data) -{ - 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; - - 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->p_data; - signal.p_data = (*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) - { - p_signal_out->link_saddrs.push_back(saddr); - } - - signal.link_saddrs.push_back(link_saddr); - - MY_LOG_I("saddr %s, p_data %p, link_saddr %s", saddr.c_str(), (*p_data), link_saddr.c_str()); - - return dc_signal_add_to_map(signal, g_datacenter.signal_in); -} - LOCAL void dc_signal_ctrl_data_create(stru_signal_ctrl &ctrl) { switch(ctrl.data_type) @@ -343,71 +319,149 @@ LOCAL void dc_signal_ctrl_data_create(stru_signal_ctrl &ctrl) } } -int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t data_type, const stru_signal_param ¶m, uint8_t ctrl_type, void *p_data, signal_change_cb cb) +LOCAL int dc_data_compare(uint8_t data_type, void *p_data, void *p_data2) { - // 先从参数表里解析,调用参数注册 - // 程序注册时,从参数表里去查找,同一个信息,使用参数表中的保存的数据值,在线程初始化时,通知所有链接此信号的信号 - // 注册时不在参数表中的,新增到动态表里,并保存到参数表里,使用缺省值 - - XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(hash, g_datacenter.siganl_param); - if(p_signal != nullptr) + if(p_data == nullptr || p_data2 == nullptr) { - dc_set_signal_val(p_data, data_type, p_signal->p_data); - p_signal->change_cb_list.push_back(cb); - return 0; + LOG_E("p_data or p_data2 is nullptr"); + return -1; } - stru_signal signal; - signal.hash = hash; - signal.saddr.assign(saddr); - signal.desc.assign(desc); - signal.data_type = data_type; - signal.p_data = p_data; - signal.param = param; - - dc_signal_add_to_map(signal, g_datacenter.siganl_param); - - p_signal = dc_find_signal(hash, g_datacenter.siganl_param); - if(p_signal != nullptr) + switch(data_type) { - if(cb) - { - p_signal->change_cb_list.push_back(cb); - } - - p_signal->ctrl_type = ctrl_type; - - return 0; - } - - return -1; -} - -int dc_signal_param_link_with_callback(const std::string &saddr, uint8_t data_type, void **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.siganl_param); - if(p_signal != nullptr) - { - if(p_signal->data_type != data_type) - { - LOG_E("saddr %s data type %s(%d) not match %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); + 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: + return (*(float *)p_data == *(float *)p_data2) ? 0 : -1; + case DATA_TYPE_D64: + return (*(double *)p_data == *(double *)p_data2) ? 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: + return (0 == strcmp((char *)p_data, (char *)p_data2)) ? 0 : -1; + default: + LOG_E("unsupported data type %d", data_type); return -1; - } - - if(cb) - { - p_signal->change_cb_list.push_back(cb); - } - (*p_data) = p_signal->p_data; - return 0; } 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) +{ + if(p_signal == nullptr || p_data == nullptr || p_default_data == nullptr) + { + LOG_E("p_signal, p_data or p_default_data is nullptr"); + return false; + } + + bool change = false; + + if(p_signal->desc != desc) + { + p_signal->desc = desc; + change = true; + } + + if(p_signal->data_type != data_type) + { + p_signal->data_type = data_type; + change = true; + } + + if(p_signal->param.min != param.min || p_signal->param.max != param.max || p_signal->param.step != param.step || p_signal->param.unit != param.unit) + { + p_signal->param = param; + change = true; + } + + if(p_signal->ctrl_type != ctrl_type) + { + p_signal->ctrl_type = ctrl_type; + change = true; + } + + if(0 != dc_data_compare(p_signal->data_type, p_data, p_signal->vec_p_data[0])) + { + change = true; + } + + if(0 != dc_data_compare(p_signal->data_type, p_default_data, p_signal->vec_p_default_data[0])) + { + change = true; + } + + 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) +{ + bool change = false; + + if(p_signal->desc != desc) + { + p_signal->desc = desc; + change = true; + } + + if(p_signal->data_type != data_type) + { + p_signal->data_type = data_type; + change = true; + } + + if(p_signal->param.min != param.min || p_signal->param.max != param.max || p_signal->param.step != param.step || p_signal->param.unit != param.unit) + { + p_signal->param = param; + change = true; + } + + if(p_signal->ctrl_type != ctrl_type) + { + p_signal->ctrl_type = ctrl_type; + 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++) + { + if(0 != dc_data_compare(p_signal->data_type, vec_p_data[i], p_signal->vec_p_data[i])) + { + change = true; + } + } + + return change; +} + + 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) @@ -523,38 +577,6 @@ LOCAL int dc_check_ctrl_val_valid(const stru_signal_ctrl &ctrl, const void *p_da return -1; } } - // else if(ctrl.data_type == DATA_TYPE_C8) - // { - // if(0 != memcmp((char *)ctrl.p_data, (char *)p_data, 8)); - // { - // LOG_E("direct ctrl value %s not match selected value %s", (char *)ctrl.p_data, (char *)p_data); - // return -1; - // } - // } - // else if(ctrl.data_type == DATA_TYPE_C32) - // { - // if(0 != memcmp((char *)ctrl.p_data, (char *)p_data, 32)); - // { - // LOG_E("direct ctrl value %s not match selected value %s", (char *)ctrl.p_data, (char *)p_data); - // return -1; - // } - // } - // else if(ctrl.data_type == DATA_TYPE_C64) - // { - // if(0 != memcmp((char *)ctrl.p_data, (char *)p_data, 64)); - // { - // LOG_E("direct ctrl value %s not match selected value %s", (char *)ctrl.p_data, (char *)p_data); - // return -1; - // } - // } - // else if(ctrl.data_type == DATA_TYPE_C128) - // { - // if(0 != memcmp((char *)ctrl.p_data, (char *)p_data, 128)); - // { - // 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); @@ -631,15 +653,23 @@ LOCAL int dc_check_ctrl_valid(const stru_signal *p_signal, SIGNAL_CTRL_STEP step } -LOCAL int dc_check_val_valid(const stru_signal *p_signal, const void *p_data) +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 *)p_signal->p_data == *(uint8_t *)p_data) + if(*(uint8_t *)current_p_data == *(uint8_t *)p_data) { - LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint8_t*)p_signal->p_data); + LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint8_t*)current_p_data); return -1; } @@ -652,9 +682,9 @@ LOCAL int dc_check_val_valid(const stru_signal *p_signal, const void *p_data) } else if(p_signal->data_type == DATA_TYPE_S8) { - if(*(int8_t*)p_signal->p_data == *(int8_t*)p_data) + if(*(int8_t*)current_p_data == *(int8_t*)p_data) { - LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(int8_t*)p_signal->p_data); + LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(int8_t*)current_p_data); return -1; } @@ -667,9 +697,9 @@ LOCAL int dc_check_val_valid(const stru_signal *p_signal, const void *p_data) } else if(p_signal->data_type == DATA_TYPE_U8) { - if(*(uint8_t*)p_signal->p_data == *(uint8_t*)p_data) + if(*(uint8_t*)current_p_data == *(uint8_t*)p_data) { - LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint8_t*)p_signal->p_data); + LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint8_t*)current_p_data); return -1; } @@ -682,9 +712,9 @@ LOCAL int dc_check_val_valid(const stru_signal *p_signal, const void *p_data) } else if(p_signal->data_type == DATA_TYPE_S16) { - if(*(int16_t*)p_signal->p_data == *(int16_t*)p_data) + if(*(int16_t*)current_p_data == *(int16_t*)p_data) { - LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(int16_t*)p_signal->p_data); + LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(int16_t*)current_p_data); return -1; } @@ -697,9 +727,9 @@ LOCAL int dc_check_val_valid(const stru_signal *p_signal, const void *p_data) } else if(p_signal->data_type == DATA_TYPE_U16) { - if(*(uint16_t*)p_signal->p_data == *(uint16_t*)p_data) + if(*(uint16_t*)current_p_data == *(uint16_t*)p_data) { - LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint16_t*)p_signal->p_data); + LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint16_t*)current_p_data); return -1; } @@ -712,9 +742,9 @@ LOCAL int dc_check_val_valid(const stru_signal *p_signal, const void *p_data) } else if(p_signal->data_type == DATA_TYPE_S32) { - if(*(int32_t*)p_signal->p_data == *(int32_t*)p_data) + if(*(int32_t*)current_p_data == *(int32_t*)p_data) { - LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(int32_t*)p_signal->p_data); + LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(int32_t*)current_p_data); return -1; } @@ -727,9 +757,9 @@ LOCAL int dc_check_val_valid(const stru_signal *p_signal, const void *p_data) } else if(p_signal->data_type == DATA_TYPE_U32) { - if(*(uint32_t*)p_signal->p_data == *(uint32_t*)p_data) + if(*(uint32_t*)current_p_data == *(uint32_t*)p_data) { - LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint32_t*)p_signal->p_data); + LOG_E("%s value %d not changed", p_signal->saddr.c_str(), *(uint32_t*)current_p_data); return -1; } @@ -742,9 +772,9 @@ LOCAL int dc_check_val_valid(const stru_signal *p_signal, const void *p_data) } else if(p_signal->data_type == DATA_TYPE_L64) { - if(*(int64_t*)p_signal->p_data == *(int64_t*)p_data) + if(*(int64_t*)current_p_data == *(int64_t*)p_data) { - LOG_E("%s value %lld not changed", p_signal->saddr.c_str(), *(int64_t*)p_signal->p_data); + LOG_E("%s value %lld not changed", p_signal->saddr.c_str(), *(int64_t*)current_p_data); return -1; } @@ -757,9 +787,9 @@ LOCAL int dc_check_val_valid(const stru_signal *p_signal, const void *p_data) } else if(p_signal->data_type == DATA_TYPE_UL64) { - if(*(uint64_t*)p_signal->p_data == *(uint64_t*)p_data) + if(*(uint64_t*)current_p_data == *(uint64_t*)p_data) { - LOG_E("%s value %llu not changed", p_signal->saddr.c_str(), *(uint64_t*)p_signal->p_data); + LOG_E("%s value %llu not changed", p_signal->saddr.c_str(), *(uint64_t*)current_p_data); return -1; } @@ -772,9 +802,9 @@ LOCAL int dc_check_val_valid(const stru_signal *p_signal, const void *p_data) } else if(p_signal->data_type == DATA_TYPE_F32) { - if(*(float*)p_signal->p_data == *(float*)p_data) + if(*(float*)current_p_data == *(float*)p_data) { - LOG_E("%s value %f not changed", p_signal->saddr.c_str(), *(float*)p_signal->p_data); + LOG_E("%s value %f not changed", p_signal->saddr.c_str(), *(float*)current_p_data); return -1; } @@ -787,9 +817,9 @@ LOCAL int dc_check_val_valid(const stru_signal *p_signal, const void *p_data) } else if(p_signal->data_type == DATA_TYPE_D64) { - if(*(double*)p_signal->p_data == *(double*)p_data) + if(*(double*)current_p_data == *(double*)p_data) { - LOG_E("%s value %f not changed", p_signal->saddr.c_str(), *(double*)p_signal->p_data); + LOG_E("%s value %f not changed", p_signal->saddr.c_str(), *(double*)current_p_data); return -1; } @@ -800,59 +830,24 @@ LOCAL int dc_check_val_valid(const stru_signal *p_signal, const void *p_data) return -1; } } - else if(p_signal->data_type == DATA_TYPE_IP) + 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) { - if(0 == memcmp((char *)p_signal->p_data, (char *)p_data, 4)) + if(0 == strcmp((char *)current_p_data, (char *)p_data)) { - LOG_E("%s value %s not changed", p_signal->saddr.c_str(), (char*)p_signal->p_data); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_MAC) - { - if(0 == memcmp((char *)p_signal->p_data, (char *)p_data, 6)) - { - LOG_E("%s value %s not changed", p_signal->saddr.c_str(), (char*)p_signal->p_data); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_C8) - { - if(0 == memcmp((char *)p_signal->p_data, (char *)p_data, 8)) - { - LOG_E("%s value %s not changed", p_signal->saddr.c_str(), (char*)p_signal->p_data); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_C32) - { - if(0 == memcmp((char *)p_signal->p_data, (char *)p_data, 32)) - { - LOG_E("%s value %s not changed", p_signal->saddr.c_str(), (char*)p_signal->p_data); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_C64) - { - if(0 == memcmp((char *)p_signal->p_data, (char *)p_data, 64)) - { - LOG_E("%s value %s not changed", p_signal->saddr.c_str(), (char*)p_signal->p_data); - return -1; - } - } - else if(p_signal->data_type == DATA_TYPE_C128) - { - if(0 == memcmp((char *)p_signal->p_data, (char *)p_data, 128)) - { - LOG_E("%s value %s not changed", p_signal->saddr.c_str(), (char*)p_signal->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*)p_signal->p_data == *(char*)p_data) + if(*(char*)current_p_data == *(char*)p_data) { - LOG_E("%s value %c not changed", p_signal->saddr.c_str(), *(char*)p_signal->p_data); + LOG_E("%s value %c not changed", p_signal->saddr.c_str(), *(char*)current_p_data); return -1; } } @@ -865,15 +860,443 @@ LOCAL int dc_check_val_valid(const stru_signal *p_signal, const void *p_data) return 0; } -int dc_signal_param_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, void *p_data) + + +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) + { + *exist_signal = signal; + return 0; + } + } + + stru_signal new_signal = signal; + conflict_it->second.push_back(&new_signal); + } + 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); + conficts.push_back(&signal); + dc_signal_map.hash_conflict_table[signal.hash] = conficts; + } + else + { + map_it->second = signal; + } + } + else + { + signal_map.emplace(signal.hash, signal); + } + } + + dc_update_global_index(signal, dc_signal_map); + + 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 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); + + + // 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_in(const std::string &saddr, const std::string &desc, const std::string &link_saddr, uint8_t data_type, void **p_data) +{ + 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; + + 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.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) + { + p_signal_out->link_saddrs.push_back(saddr); + } + + signal.link_saddrs.push_back(link_saddr); + + MY_LOG_I("saddr %s, p_data %p, link_saddr %s", saddr.c_str(), (*p_data), link_saddr.c_str()); + + 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, const stru_signal_param ¶m, uint8_t ctrl_type, void *p_data, void *p_default_data, signal_change_cb cb) +{ + if(p_data == nullptr || p_default_data == nullptr) + { + MY_LOG_E("p_data or p_default_data is nullptr"); + return -1; + } + XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); - stru_signal *p_signal = dc_find_signal(hash, g_datacenter.siganl_param); + stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_ao); + if(p_signal != nullptr) + { + if(true == dc_signal_ao_add_check(p_signal, desc, data_type, param, ctrl_type, p_data, p_default_data)) + { + dc_set_param_cfg_change(true); + } + else + { + dc_set_signal_val(p_data, data_type, p_signal->vec_p_data[0]); + } + + // delete p_signal->vec_p_data[0]; + 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(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; + signal.param = param; + signal.ctrl_type = ctrl_type; + + dc_signal_add_to_map(signal, g_datacenter.signal_ao); + + p_signal = dc_find_signal(hash, g_datacenter.signal_ao); + if(p_signal != nullptr ) + { + p_signal->vec_p_data.push_back(p_data); + p_signal->vec_p_default_data.push_back(p_default_data); + + if(cb) + { + p_signal->change_cb_list.push_back(cb); + } + + return 0; + } + + return -1; +} + +int dc_signal_ao_link_with_callback(const std::string &saddr, uint8_t data_type, void **p_data, signal_change_cb cb) +{ + 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(hash, g_datacenter.signal_ao); + if(p_signal != nullptr) + { + if(cb) + { + p_signal->change_cb_list.push_back(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) +{ + 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(hash, 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, 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 cb : p_signal->change_cb_list) + { + if(cb) + { + cb(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", saddr.c_str()); + + return -1; +} + +int dc_signal_ao_set_val_without_check(const std::string &saddr, uint8_t data_type, void *p_data) +{ + 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(hash, 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; + } + + dc_set_signal_val(p_signal->vec_p_data[0], data_type, 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, const stru_signal_param ¶m, uint8_t ctrl_type, std::vector &vec_p_data, std::vector &vec_p_default_data, signal_change_cb cb) +{ + // 先从参数表里解析,调用参数注册 + // 程序注册时,从参数表里去查找,同一个信息,使用参数表中的保存的数据值,在线程初始化时,通知所有链接此信号的信号 + // 注册时不在参数表中的,新增到动态表里,并保存到参数表里,使用缺省值 + + if(vec_p_data.size() != vec_p_default_data.size() || vec_p_data.empty()) + { + MY_LOG_E("vec_p_data size %ld, vec_p_default_data size %ld", vec_p_data.size(), vec_p_default_data.size()); + return -1; + } + + XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); + stru_signal *p_signal = dc_find_signal(hash, 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)) + { + dc_set_param_cfg_change(true); + } + else + { + for(size_t i = 0; i < vec_p_data.size(); i++) + { + dc_set_signal_val(vec_p_data[i], data_type, p_signal->vec_p_data[i]); + } + } + + for(size_t i = 0; i < vec_p_data.size(); i++) + { + // delete p_signal->vec_p_data[i]; + dc_delete_signal_data(p_signal->vec_p_data[i], data_type); + p_signal->vec_p_data[i] = vec_p_data[i]; + } + + p_signal->change_cb_list.push_back(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; + signal.param = param; + signal.ctrl_type = ctrl_type; + + dc_signal_add_to_map(signal, g_datacenter.signal_param); + + p_signal = dc_find_signal(hash, g_datacenter.signal_param); + if(p_signal != nullptr ) + { + for(size_t i = 0; i < vec_p_data.size(); i++) + { + p_signal->vec_p_data.push_back(vec_p_data[i]); + } + + if(cb) + { + p_signal->change_cb_list.push_back(cb); + } + return 0; + } + + return -1; +} + +int dc_signal_param_link_with_callback(const std::string &saddr, uint8_t data_type, 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); + if(p_signal != nullptr) + { + if(p_signal->data_type != data_type) + { + LOG_E("saddr %s data type %s(%d) not match %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(cb) + { + p_signal->change_cb_list.push_back(cb); + } + + for(size_t i = 0; i < vec_p_data.size(); i++) + { + vec_p_data.push_back(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) +{ + 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(hash, 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; @@ -886,7 +1309,7 @@ int dc_signal_param_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, str } else if(step == SIGNAL_CTRL_STEP::DIRECT) { - dc_set_signal_val(p_signal->p_data, ctrl.data_type, p_data); + 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) @@ -903,7 +1326,7 @@ int dc_signal_param_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, str { if(cb != nullptr) { - cb(saddr, step, ctrl.data_type, p_data); + cb(saddr, step, ctrl.data_type, setting_zone, p_data); } } @@ -922,11 +1345,17 @@ int dc_signal_param_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, str return -1; } -int dc_signal_param_set_val_without_check(const std::string &saddr, uint8_t data_type, void *p_data) +int dc_signal_param_set_val_without_check(const std::string &saddr, uint8_t data_type, uint8_t setting_zone, void *p_data) { + 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(hash, g_datacenter.siganl_param); - if(p_signal != nullptr) + stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_param); + if(p_signal != nullptr && setting_zone < p_signal->vec_p_data.size()) { if(p_signal->data_type != data_type) { @@ -935,7 +1364,7 @@ int dc_signal_param_set_val_without_check(const std::string &saddr, uint8_t data return -1; } - dc_set_signal_val(p_signal->p_data, data_type, p_data); + dc_set_signal_val(p_signal->vec_p_data[setting_zone], data_type, p_data); return 0; } @@ -945,17 +1374,23 @@ int dc_signal_param_set_val_without_check(const std::string &saddr, uint8_t data 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) { + 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.p_data = p_data; + signal.vec_p_data.push_back(p_data); - dc_signal_add_to_map(signal, g_datacenter.siganl_yk); + dc_signal_add_to_map(signal, g_datacenter.signal_yk); - stru_signal *p_signal = dc_find_signal(signal.hash, g_datacenter.siganl_yk); + stru_signal *p_signal = dc_find_signal(signal.hash, g_datacenter.signal_yk); if(p_signal != nullptr) { if(cb) @@ -963,11 +1398,6 @@ int dc_signal_yk(const std::string &saddr, const std::string &desc, uint8_t data p_signal->change_cb_list.push_back(cb); } - // p_signal->ctrl.step = SIGNAL_CTRL_STEP::READY; - // p_signal->ctrl.type = ctrl_type; - // p_signal->ctrl.data_type = data_type; - // dc_signal_ctrl_data_create(p_signal->ctrl); - p_signal->ctrl_type = ctrl_type; return 0; @@ -978,16 +1408,22 @@ int dc_signal_yk(const std::string &saddr, const std::string &desc, uint8_t data int dc_signal_yk_link_with_callback(const std::string &saddr, uint8_t data_type, void **p_data, signal_change_cb cb) { + 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(hash, g_datacenter.siganl_yk); + stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_yk); if(p_signal != nullptr) { if(cb) { p_signal->change_cb_list.push_back(cb); } - (*p_data) = p_signal->p_data; - return 0; + (*p_data) = p_signal->vec_p_data.empty() ? nullptr : p_signal->vec_p_data[0]; + return (*p_data) != nullptr ? 0 : -1; } return -1; @@ -995,8 +1431,14 @@ int dc_signal_yk_link_with_callback(const std::string &saddr, uint8_t data_type, int dc_signal_yk_set_status(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, void *p_data) { + 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(hash, g_datacenter.siganl_yk); + stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_yk); if(p_signal != nullptr) { if(0 == dc_check_ctrl_valid(p_signal, step, ctrl, p_data)) @@ -1008,7 +1450,7 @@ int dc_signal_yk_set_status(const std::string &saddr, SIGNAL_CTRL_STEP step, str } else if(step == SIGNAL_CTRL_STEP::DIRECT) { - dc_set_signal_val(p_signal->p_data, ctrl.data_type, p_data); + 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) @@ -1025,7 +1467,7 @@ int dc_signal_yk_set_status(const std::string &saddr, SIGNAL_CTRL_STEP step, str { if(cb != nullptr) { - cb(saddr, step, ctrl.data_type, p_data); + cb(saddr, step, ctrl.data_type, 0, p_data); } } @@ -1040,7 +1482,7 @@ int dc_signal_yk_set_status(const std::string &saddr, SIGNAL_CTRL_STEP step, str } LOG_E("saddr %s not found in yk table", saddr.c_str()); - + return -1; } @@ -1158,8 +1600,13 @@ uint8_t dc_get_data_type_len(uint8_t data_type) std::string dc_get_signal_val(void *p_data, uint8_t data_type) { + if(NULL == p_data) + { + return ""; + } + std::string str = ""; - char temp[32] = {0}; + char temp[128] = {0}; char *ptr = NULL; switch(data_type) @@ -1211,7 +1658,9 @@ std::string dc_get_signal_val(void *p_data, uint8_t data_type) case DATA_TYPE_C32: case DATA_TYPE_C64: case DATA_TYPE_C128: - str = (char *)p_data; + // 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); @@ -1275,7 +1724,7 @@ LOCAL int dc_set_signal_val(void *p_data, uint8_t data_type, void *set_data) case DATA_TYPE_C32: case DATA_TYPE_C64: // case DATA_TYPE_C128: - strncpy((char *)p_data, (char *)set_data, data_type); + strncpy((char *)p_data, (char *)set_data, dc_get_data_type_len(data_type)); break; case DATA_TYPE_C1: *(char*)p_data = *(char*)set_data; @@ -1288,12 +1737,88 @@ LOCAL int dc_set_signal_val(void *p_data, uint8_t data_type, void *set_data) 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) 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: + 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) { stru_signal *p_signal = dc_find_out_signal(saddr); if(p_signal != nullptr) { - return dc_set_signal_val(p_signal->p_data, p_signal->data_type, set_data); + return dc_set_signal_val(p_signal->vec_p_data[0], p_signal->data_type, set_data); } return -1; @@ -1393,6 +1918,171 @@ void *dc_create_data_ptr_by_type(uint8_t data_type) } } +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: + delete [] static_cast(p_data); + break; + default: + MY_LOG_E("Unknown data_type %d for delete", data_type); + break; + } +} + + + +void dc_param_group_add(const dc_param_group_info &group) +{ + std::lock_guard lock(g_param_groups_mutex); + g_param_groups.push_back(group); +} + +void dc_param_group_clear() +{ + std::lock_guard lock(g_param_groups_mutex); + g_param_groups.clear(); +} + +std::vector dc_param_group_get_all() +{ + std::lock_guard lock(g_param_groups_mutex); + return g_param_groups; +} + +void dc_param_cfg_check() +{ + if (false == dc_get_param_cfg_change()) return; + + using namespace tinyxml2; + + XMLDocument doc; + doc.InsertEndChild(doc.NewDeclaration()); + + XMLElement *root = doc.NewElement("param"); + doc.InsertEndChild(root); + + XMLElement *ao_elem = doc.NewElement("Ao"); + XMLElement *param_elem = doc.NewElement("Param"); + + auto groups = dc_param_group_get_all(); + int ao_no = 0, param_no = 0; + + for (auto &group : groups) + { + XMLElement *sig_elem = doc.NewElement("Signal"); + + std::string desc; + uint8_t data_type; + stru_signal_param param; + uint8_t ctrl_type; + std::vector vec_p_data; + std::vector vec_p_default_data; + + if (0 != dc_get_param_signal_info(group.saddr, desc, data_type, param, ctrl_type, vec_p_data, vec_p_default_data)) + continue; + + if (group.num >= 1) + { + // Param 段:多值参数 + sig_elem->SetAttribute("no", param_no++); + sig_elem->SetAttribute("saddr", group.saddr.c_str()); + sig_elem->SetAttribute("desc", group.desc.c_str()); + sig_elem->SetAttribute("type", dc_get_data_type_str_by_id(group.data_type).c_str()); + sig_elem->SetAttribute("min", group.min); + sig_elem->SetAttribute("max", group.max); + sig_elem->SetAttribute("step", group.step); + sig_elem->SetAttribute("unit", group.unit.c_str()); + sig_elem->SetAttribute("num", group.num); + + for (int i = 0; i < group.num && i < (int)vec_p_data.size(); i++) + { + XMLElement *item = doc.NewElement("Item"); + item->SetAttribute("no", i); + item->SetAttribute("value", dc_get_signal_val(vec_p_data[i], data_type).c_str()); + item->SetAttribute("default", i < (int)vec_p_default_data.size() ? + dc_get_signal_val(vec_p_default_data[i], data_type).c_str() : ""); + sig_elem->InsertEndChild(item); + } + + param_elem->InsertEndChild(sig_elem); + } + else + { + // Ao 段:单值参数 + sig_elem->SetAttribute("no", ao_no++); + sig_elem->SetAttribute("saddr", group.saddr.c_str()); + sig_elem->SetAttribute("desc", group.desc.c_str()); + sig_elem->SetAttribute("type", dc_get_data_type_str_by_id(group.data_type).c_str()); + sig_elem->SetAttribute("min", group.min); + sig_elem->SetAttribute("max", group.max); + sig_elem->SetAttribute("step", group.step); + sig_elem->SetAttribute("unit", group.unit.c_str()); + + if (!vec_p_data.empty()) + sig_elem->SetAttribute("value", dc_get_signal_val(vec_p_data[0], data_type).c_str()); + if (!vec_p_default_data.empty()) + sig_elem->SetAttribute("default", dc_get_signal_val(vec_p_default_data[0], data_type).c_str()); + + ao_elem->InsertEndChild(sig_elem); + } + } + + root->InsertEndChild(ao_elem); + root->InsertEndChild(param_elem); + + if (XML_SUCCESS == doc.SaveFile(DC_PARAM_PATH)) + { + dc_set_param_cfg_change(false); + MY_LOG_I("param config file saved to %s", DC_PARAM_PATH); + } + else + { + MY_LOG_E("failed to save param config file to %s", DC_PARAM_PATH); + } +} LOCAL void dc_show_signals(stru_signal_map &dc_signal_map) @@ -1441,7 +2131,7 @@ LOCAL void dc_show_signals(stru_signal_map &dc_signal_map) << left << setw(COL_SADDR) << signal.saddr << setw(COL_DESC) << signal.desc << setw(COL_TYPE) << dc_get_data_type_str_by_id(signal.data_type) - << setw(COL_VAL) << dc_get_signal_val(signal.p_data, signal.data_type) + << setw(COL_VAL) << dc_get_signal_val(signal.vec_p_data[0], signal.data_type) << setw(COL_LINK) << link_str << endl; } @@ -1492,15 +2182,25 @@ LOCAL void dc_show_yk_signals() using namespace std; cout << "yk signals: " << endl; - dc_show_signals(g_datacenter.siganl_yk); + 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.siganl_param); + dc_show_signals(g_datacenter.signal_param); } @@ -1511,6 +2211,7 @@ LOCAL void cmd_dc(int argc, char *argv[]) datacenter out ----------> 查看out信号信息\n\ datacenter in ----------> 查看in信号信息\n\ datacenter yk ----------> 查看yk信号信息\n\ + datacenter ao ----------> 查看ao信号信息\n\ datacenter param ----------> 查看param信号信息\n\ datacenter all ----------> 查看所有信号信息\n"; @@ -1533,6 +2234,10 @@ LOCAL void cmd_dc(int argc, char *argv[]) { 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(); @@ -1542,6 +2247,7 @@ LOCAL void cmd_dc(int argc, char *argv[]) dc_show_out_signals(); dc_show_in_signals(); dc_show_yk_signals(); + dc_show_ao_signals(); dc_show_param_signals(); } } diff --git a/src/system/libiec61850m/src/iec61850m.cpp b/src/system/libiec61850m/src/iec61850m.cpp index 36ce4b0..633ebd8 100644 --- a/src/system/libiec61850m/src/iec61850m.cpp +++ b/src/system/libiec61850m/src/iec61850m.cpp @@ -157,7 +157,7 @@ void iec61850m_init() } } -void iec61850m_signal_change_callback(std::string saddr, SIGNAL_CTRL_STEP step, uint8_t data_type, void *p_data) +void iec61850m_signal_change_callback(std::string saddr, SIGNAL_CTRL_STEP step, uint8_t data_type, uint8_t setting_zone, void *p_data) { std::string value = ""; if(p_data) @@ -232,7 +232,17 @@ int iec61850m_signal_init(stru_mms_m_config &cfg) for(uint16_t i = 0; i < cfg.st_num; i++) { uint8_t type_local = g_mms_m_type_to_local_type[cfg.p_st_sig[i].data_type]; - ret |= dc_signal_out(cfg.p_st_sig[i].saddr, cfg.p_st_sig[i].desc, type_local, cfg.p_st_sig[i].p_data); + + std::string saddr = cfg.p_st_sig[i].saddr; + std::string desc = cfg.p_st_sig[i].desc; + void *p_data = cfg.p_st_sig[i].vec_p_data.empty() ? nullptr : cfg.p_st_sig[i].vec_p_data[0]; + if(p_data == nullptr) + { + MY_LOG_E("st saddr %s, desc %s, p_data %p", saddr.c_str(), desc.c_str(), p_data); + return -1; + } + + ret |= dc_signal_out(saddr, desc, type_local, p_data); } if(ret != 0) @@ -244,7 +254,15 @@ int iec61850m_signal_init(stru_mms_m_config &cfg) for(uint16_t i = 0; i < cfg.mx_num; i++) { uint8_t type_local = g_mms_m_type_to_local_type[cfg.p_mx_sig[i].data_type]; - ret |= dc_signal_out(cfg.p_mx_sig[i].saddr, cfg.p_mx_sig[i].desc, type_local, cfg.p_mx_sig[i].p_data); + + void *p_data = cfg.p_mx_sig[i].vec_p_data.empty() ? nullptr : cfg.p_mx_sig[i].vec_p_data[0]; + if(p_data == nullptr) + { + MY_LOG_E("mx saddr %s, desc %s, p_data %p", cfg.p_mx_sig[i].saddr, cfg.p_mx_sig[i].desc, p_data); + return -1; + } + + ret |= dc_signal_out(cfg.p_mx_sig[i].saddr, cfg.p_mx_sig[i].desc, type_local, p_data); } if(ret != 0) @@ -257,7 +275,15 @@ int iec61850m_signal_init(stru_mms_m_config &cfg) { uint8_t type_local = g_mms_m_type_to_local_type[cfg.p_co_sig[i].sig.data_type]; uint8_t ctrl_type_local = g_mms_m_ctrl_type_to_local_ctrl_type[cfg.p_co_sig[i].ctrl_type]; - ret |= dc_signal_yk(cfg.p_co_sig[i].sig.saddr, cfg.p_co_sig[i].sig.desc, type_local, ctrl_type_local, cfg.p_co_sig[i].sig.p_data, iec61850m_signal_change_callback); + + void *p_data = cfg.p_co_sig[i].sig.vec_p_data.empty() ? nullptr : cfg.p_co_sig[i].sig.vec_p_data[0]; + if(p_data == nullptr) + { + MY_LOG_E("co saddr %s, desc %s, p_data %p", cfg.p_co_sig[i].sig.saddr, cfg.p_co_sig[i].sig.desc, p_data); + return -1; + } + + ret |= dc_signal_yk(cfg.p_co_sig[i].sig.saddr, cfg.p_co_sig[i].sig.desc, type_local, ctrl_type_local, p_data, iec61850m_signal_change_callback); } if(ret != 0) @@ -273,10 +299,38 @@ int iec61850m_signal_init(stru_mms_m_config &cfg) param.max = cfg.p_ao_sig[i].max; param.step = cfg.p_ao_sig[i].step; param.unit = cfg.p_ao_sig[i].unit; - param.default_value = cfg.p_ao_sig[i].p_default ? dc_get_signal_val(cfg.p_ao_sig[i].p_default, cfg.p_ao_sig[i].sig.data_type) : ""; + // param.default_value = cfg.p_ao_sig[i].p_default ? dc_get_signal_val(cfg.p_ao_sig[i].p_default, cfg.p_ao_sig[i].sig.data_type) : ""; uint8_t type_local = g_mms_m_type_to_local_type[cfg.p_ao_sig[i].sig.data_type]; - ret |= dc_signal_param(cfg.p_ao_sig[i].sig.saddr, cfg.p_ao_sig[i].sig.desc, type_local, param, cfg.p_ao_sig[i].ctrl_type, cfg.p_ao_sig[i].sig.p_data, iec61850m_signal_change_callback); + + void *p_data = cfg.p_ao_sig[i].sig.vec_p_data.empty() ? nullptr : cfg.p_ao_sig[i].sig.vec_p_data[0]; + void *p_def_data = cfg.p_ao_sig[i].vec_p_default.empty() ? nullptr : cfg.p_ao_sig[i].vec_p_default[0]; + + if(p_data == nullptr || p_def_data == nullptr) + { + MY_LOG_E("ao saddr %s, desc %s, p_data %p, p_def_data %p", cfg.p_ao_sig[i].sig.saddr, cfg.p_ao_sig[i].sig.desc, p_data, p_def_data); + return -1; + } + + ret |= dc_signal_ao(cfg.p_ao_sig[i].sig.saddr, cfg.p_ao_sig[i].sig.desc, type_local, param, cfg.p_ao_sig[i].ctrl_type, p_data, p_def_data, iec61850m_signal_change_callback); + } + + if(ret != 0) + { + LOG_E("dc_signal_ao failed, ret %d", ret); + return -1; + } + + for(uint16_t i = 0; i < cfg.param_num; i++) + { + stru_signal_param param; + param.min = cfg.p_param_sig[i].min; + param.max = cfg.p_param_sig[i].max; + param.step = cfg.p_param_sig[i].step; + param.unit = cfg.p_param_sig[i].unit; + + uint8_t type_local = g_mms_m_type_to_local_type[cfg.p_param_sig[i].sig.data_type]; + ret |= dc_signal_param(cfg.p_param_sig[i].sig.saddr, cfg.p_param_sig[i].sig.desc, type_local, param, cfg.p_param_sig[i].ctrl_type, cfg.p_param_sig[i].sig.vec_p_data, cfg.p_param_sig[i].vec_p_default, iec61850m_signal_change_callback); } if(ret != 0) diff --git a/src/system/libself_ptl/inc/method.h b/src/system/libself_ptl/inc/method.h index 965d89f..ce0bede 100644 --- a/src/system/libself_ptl/inc/method.h +++ b/src/system/libself_ptl/inc/method.h @@ -5,7 +5,7 @@ #include "myIcp67.h" #include "self_ptl.h" -void param_pop_out(stru_icp67 *p_icp67, uint16_t addr, uint8_t type, uint8_t len, uint8_t *p_data); +void ao_pop_out(stru_icp67 *p_icp67, uint16_t addr, uint8_t type, uint8_t len, uint8_t *p_data); void iec_point_tbl_pop_out(stru_icp67 *p_icp67, uint16_t info_addr, uint16_t num, uint8_t *p_data); void self_check_pop_out(stru_icp67 *p_icp67, stru_data_info *p_data, uint16_t addr); void dir_pop_out(stru_icp67 *p_icp67, uint8_t *p_name, uint8_t len, uint32_t attr, uint32_t size, uint8_t follow); diff --git a/src/system/libself_ptl/inc/self_ptl.h b/src/system/libself_ptl/inc/self_ptl.h index 0eb9dd0..6bea377 100644 --- a/src/system/libself_ptl/inc/self_ptl.h +++ b/src/system/libself_ptl/inc/self_ptl.h @@ -55,9 +55,9 @@ typedef struct typedef struct { stru_self_ptl_cfg_param *p_param; - void *p_data; - void *p_default_data; stru_signal_ctrl *p_ctrl; + std::vector vec_p_data; + std::vector vec_p_default_data; }stru_self_ptl_cfg_param_data; @@ -68,6 +68,7 @@ typedef struct std::vector co_vec; std::vector dd_vec; + std::vector ao_vec; std::vector param_vec; }stru_self_ptl_cfg_data; diff --git a/src/system/libself_ptl/src/method.cpp b/src/system/libself_ptl/src/method.cpp index b19df0a..620a292 100644 --- a/src/system/libself_ptl/src/method.cpp +++ b/src/system/libself_ptl/src/method.cpp @@ -48,9 +48,9 @@ typedef struct uint16_t tx_cnt; uint16_t per_cnt; uint16_t offset; -}stru_local_param_get; +}stru_local_ao_get; -LOCAL stru_local_param_get g_local_param_get; +LOCAL stru_local_ao_get g_local_ao_get; typedef struct { @@ -106,7 +106,7 @@ LOCAL int file_write(const char *file_name, uint32_t offset, uint8_t *p_data, ui LOCAL int file_read(const char *file_name, uint32_t offset, uint8_t *p_data, uint16_t len); LOCAL int file_size_get(const char *file_name, uint32_t *p_size); -LOCAL void test_param_get(stru_icp67 *p_icp67, stru_genneral_method *p_method); +LOCAL void test_ao_get(stru_icp67 *p_icp67, stru_genneral_method *p_method); LOCAL void test_iec_point_tbl_get(stru_icp67 *p_icp67, stru_genneral_method *p_method); LOCAL void test_time_set(stru_icp67 *p_icp67, stru_genneral_method *p_method); LOCAL void test_self_check_get(stru_icp67 *p_icp67, stru_genneral_method *p_method); @@ -130,7 +130,7 @@ std::map g_map_iec_point_tbl_decode = typedef void (* local_test)(stru_icp67 *p_icp67, stru_genneral_method *p_method); std::map g_map_local_test = { - {1, test_param_get}, + {1, test_ao_get}, {3, test_iec_point_tbl_get}, {5, test_time_set}, {6, test_self_check_get}, @@ -139,32 +139,37 @@ std::map g_map_local_test = }; -void param_pop_out(stru_icp67 *p_icp67, uint16_t addr, uint8_t type, uint8_t len, uint8_t *p_data) +void ao_pop_out(stru_icp67 *p_icp67, uint16_t addr, uint8_t type, uint8_t len, uint8_t *p_data) { if(NULL == p_icp67 || NULL == p_data) { - LOG_E("param_pop_out: invalid parameter"); + LOG_E("ao_pop_out: invalid parameter"); return; } - + stru_self_ptl_cfg_data *p_app_cfg_data = self_ptl_cfg_data_ptr_get(); - uint16_t pos = g_local_param_get.offset + g_local_param_get.rx_cnt; - stru_self_ptl_cfg_param_data *p_param_data = &p_app_cfg_data->param_vec[pos]; + uint16_t pos = g_local_ao_get.offset + g_local_ao_get.rx_cnt; + stru_self_ptl_cfg_param_data *p_ao_data = &p_app_cfg_data->ao_vec[pos]; - if(p_param_data->p_param->base.inf == addr && p_param_data->p_param->type == type) + if(p_ao_data->p_param->base.inf == addr && p_ao_data->p_param->type == type && dc_get_data_type_len(type) == len) { - // dc_signal_param_set_val(p_param_data->p_param->base.saddr, SIGNAL_CTRL_STEP::SELECT, type, p_data); - // dc_signal_param_set_val(p_param_data->p_param->base.saddr, SIGNAL_CTRL_STEP::DIRECT, type, p_data); + // dc_signal_param_set_val(p_ao_data->p_param->base.saddr, SIGNAL_CTRL_STEP::SELECT, type, p_data); + // dc_signal_param_set_val(p_ao_data->p_param->base.saddr, SIGNAL_CTRL_STEP::DIRECT, type, p_data); - dc_signal_param_set_val_without_check(p_param_data->p_param->base.saddr, type, p_data); + + if(0 != dc_signal_ao_set_val_without_check(p_ao_data->p_param->base.saddr, type, (void *)p_data)) + { + LOG_E("dc_signal_ao_set_val_without_check failed,saddr %s, desc %s, inf %d, type %d", + p_ao_data->p_param->base.saddr.c_str(), p_ao_data->p_param->base.desc.c_str(), p_ao_data->p_param->base.inf, type); + } } - g_local_param_get.rx_cnt++; - if(g_local_param_get.rx_cnt == g_local_param_get.tx_cnt) + g_local_ao_get.rx_cnt++; + if(g_local_ao_get.rx_cnt == g_local_ao_get.tx_cnt) { - g_local_param_get.offset += g_local_param_get.tx_cnt; + g_local_ao_get.offset += g_local_ao_get.tx_cnt; g_flag[1] = 1; } @@ -892,19 +897,19 @@ LOCAL int file_size_get(const char *file_name, uint32_t *p_size) } -LOCAL void test_param_get(stru_icp67 *p_icp67, stru_genneral_method *p_method) +LOCAL void test_ao_get(stru_icp67 *p_icp67, stru_genneral_method *p_method) { stru_self_ptl_cfg_data *p_app_cfg_data = self_ptl_cfg_data_ptr_get(); uint16_t cnt = 0; - if(g_local_param_get.offset >= p_app_cfg_data->param_vec.size()) + if(g_local_ao_get.offset >= p_app_cfg_data->ao_vec.size()) { - for(uint16_t i = 0; i < p_app_cfg_data->param_vec.size(); i++) + for(uint16_t i = 0; i < p_app_cfg_data->ao_vec.size(); i++) { - stru_self_ptl_cfg_param_data *p_data = &p_app_cfg_data->param_vec[i]; + stru_self_ptl_cfg_param_data *p_data = &p_app_cfg_data->ao_vec[i]; - std::string val = dc_get_signal_val(p_data->p_data, p_data->p_param->type); + std::string val = dc_get_signal_val(p_data->vec_p_data[0], p_data->p_param->type); stru_self_ptl_cfg_base *p_base = &p_data->p_param->base; @@ -916,27 +921,26 @@ LOCAL void test_param_get(stru_icp67 *p_icp67, stru_genneral_method *p_method) } uint16_t i = 0; - if(p_app_cfg_data->param_vec[g_local_param_get.offset].p_param->type == DATA_TYPE_C32) + if(p_app_cfg_data->ao_vec[g_local_ao_get.offset].p_param->type == DATA_TYPE_C32) { - g_local_param_get.per_cnt = 10; + g_local_ao_get.per_cnt = 10; } - stru_ti_1_2_data data[g_local_param_get.per_cnt] = {0}; - for(i = g_local_param_get.offset; cnt < g_local_param_get.per_cnt && i < p_app_cfg_data->param_vec.size(); i++,cnt++) + stru_ti_1_2_data data[g_local_ao_get.per_cnt] = {0}; + for(i = g_local_ao_get.offset; cnt < g_local_ao_get.per_cnt && i < p_app_cfg_data->ao_vec.size(); i++,cnt++) { - - data[cnt].data_addr = p_app_cfg_data->param_vec[i].p_param->base.inf; - data[cnt].data_type = p_app_cfg_data->param_vec[i].p_param->type; - data[cnt].data_len = dc_get_data_type_len(p_app_cfg_data->param_vec[i].p_param->type); + data[cnt].data_addr = p_app_cfg_data->ao_vec[i].p_param->base.inf; + data[cnt].data_type = p_app_cfg_data->ao_vec[i].p_param->type; + data[cnt].data_len = dc_get_data_type_len(p_app_cfg_data->ao_vec[i].p_param->type); } g_flag[1] = 0; - g_local_param_get.rx_cnt = 0; - g_local_param_get.tx_cnt = cnt; + g_local_ao_get.rx_cnt = 0; + g_local_ao_get.tx_cnt = cnt; - LOG_I("param_get: i %d, cnt %d, tx_cnt %d, offset %d, size %d", i, cnt, g_local_param_get.tx_cnt, g_local_param_get.offset, p_app_cfg_data->param_vec.size()); - p_method->param_get_cb(p_icp67, data, cnt); + LOG_I("ao_get: i %d, cnt %d, tx_cnt %d, offset %d, size %d", i, cnt, g_local_ao_get.tx_cnt, g_local_ao_get.offset, p_app_cfg_data->ao_vec.size()); + p_method->ao_get_cb(p_icp67, data, cnt); } LOCAL void test_iec_point_tbl_get(stru_icp67 *p_icp67, stru_genneral_method *p_method) @@ -1118,19 +1122,20 @@ LOCAL void cmd_self_ptl(int argc, char *argv[]) g_flag[1] = 1; stru_icp67 *p_icp67 = self_ptl_icp67_ptr_get(); - g_local_param_get.offset = 0; - g_local_param_get.per_cnt = 40; + g_local_ao_get.offset = 0; + g_local_ao_get.per_cnt = 40; } else if(argc == 3) { stru_self_ptl_cfg_data *p_cfg = self_ptl_cfg_data_ptr_get(); - for(uint16_t i = 0; i < p_cfg->param_vec.size(); i++) + for(uint16_t i = 0; i < p_cfg->ao_vec.size(); i++) { - stru_self_ptl_cfg_param_data *p_data = &p_cfg->param_vec[i]; + stru_self_ptl_cfg_param_data *p_data = &p_cfg->ao_vec[i]; stru_self_ptl_cfg_base *p_base = &p_data->p_param->base; - std::string val = dc_get_signal_val(p_data->p_data, p_data->p_param->type); + std::string val = dc_get_signal_val(p_data->vec_p_data[0], p_data->p_param->type); + std::string default_val = dc_get_signal_val(p_data->vec_p_default_data[0], p_data->p_param->type); printf("no %06d, saddr %s, desc %s, inf %04x, type %04d, len %04d, val %s, default %s\n", - i, p_base->saddr.c_str(), p_base->desc.c_str(), p_base->inf, p_data->p_param->type, dc_get_data_type_len(p_data->p_param->type), val.c_str(), p_data->p_param->default_value.c_str()); + i, p_base->saddr.c_str(), p_base->desc.c_str(), p_base->inf, p_data->p_param->type, dc_get_data_type_len(p_data->p_param->type), val.c_str(), default_val.c_str()); } } } diff --git a/src/system/libself_ptl/src/self_ptl.cpp b/src/system/libself_ptl/src/self_ptl.cpp index de6abd1..c1e8203 100644 --- a/src/system/libself_ptl/src/self_ptl.cpp +++ b/src/system/libself_ptl/src/self_ptl.cpp @@ -27,9 +27,9 @@ stru_self_ptl g_self_ptl = { .method = { - .param_get_cb = NULL, - .param_pop_out_cb = param_pop_out, - .param_set_cb = NULL, + .ao_get_cb = NULL, + .ao_pop_out_cb = ao_pop_out, + .ao_set_cb = NULL, .iec_point_tbl_get_cb = NULL, .iec_point_tbl_pop_out_cb = iec_point_tbl_pop_out, .time_set_cb = NULL, @@ -476,15 +476,20 @@ LOCAL int self_ptl_cfg_init() stru_self_ptl_cfg_data *p_cfg_data = &g_self_ptl_cfg_data; + p_cfg_data->st_vec.reserve(p_cfg->st_vec.size() + 1); + for(uint32_t i = 0; i < p_cfg->st_vec.size(); i++) { uint8_t *p_u8 = new uint8_t; uint8_t *p_u8_last = new uint8_t; (*p_u8) = 0; (*p_u8_last) = 0; + + p_cfg_data->st_vec.push_back({&p_cfg->st_vec[i], p_u8, p_u8_last}); } + p_cfg_data->mx_vec.reserve(p_cfg->mx_vec.size() + 1); for(uint32_t i = 0; i < p_cfg->mx_vec.size(); i++) { float *p_f = new float; @@ -494,6 +499,7 @@ LOCAL int self_ptl_cfg_init() p_cfg_data->mx_vec.push_back({&p_cfg->mx_vec[i], p_f, p_f_last}); } + p_cfg_data->co_vec.reserve(p_cfg->co_vec.size() + 1); for(uint32_t i = 0; i < p_cfg->co_vec.size(); i++) { uint8_t *p_u8 = new uint8_t; @@ -502,7 +508,8 @@ LOCAL int self_ptl_cfg_init() (*p_u8_last) = 0; stru_signal_ctrl *p_ctrl = new stru_signal_ctrl; - if(nullptr == p_ctrl) { + if(nullptr == p_ctrl) + { LOG_E("self_ptl_cfg_init new stru_signal_ctrl failed"); return -1; } @@ -520,6 +527,7 @@ LOCAL int self_ptl_cfg_init() p_cfg_data->co_vec.push_back({&p_cfg->co_vec[i], p_u8, p_u8_last, p_ctrl}); } + p_cfg_data->dd_vec.reserve(p_cfg->dd_vec.size() + 1); for(uint32_t i = 0; i < p_cfg->dd_vec.size(); i++) { float *p_f = new float; @@ -529,23 +537,54 @@ LOCAL int self_ptl_cfg_init() p_cfg_data->dd_vec.push_back({&p_cfg->dd_vec[i], p_f, p_f_last}); } - for(uint32_t i = 0; i < p_cfg->param_vec.size(); i++) + MY_LOG_I("ao signals: %d", (int)p_cfg->ao_vec.size()); + + p_cfg_data->ao_vec.reserve(p_cfg->ao_vec.size() + 1); + for(uint32_t i = 0; i < p_cfg->ao_vec.size(); i++) { - stru_self_ptl_cfg_param *p_param = &p_cfg->param_vec[i]; - void *p_data = dc_create_data_ptr_by_type(p_param->type); - if(nullptr == p_data) + stru_self_ptl_cfg_param *p_ao = &p_cfg->ao_vec[i]; + + stru_signal_ctrl *p_ctrl = new stru_signal_ctrl; + if(nullptr == p_ctrl) { - LOG_E("self_ptl_cfg_init dc_create_data_ptr_by_type failed, type:%d", p_param->type); + LOG_E("self_ptl_cfg_init dc_create_data_ptr_by_type failed, type:%d", p_ao->type); return -1; } - void *p_default_data = dc_create_data_ptr_by_type(p_param->type); - if(nullptr == p_default_data) + p_ctrl->type = SIGNAL_CTRL_TYPE::SBO_NORMAL; + p_ctrl->step = SIGNAL_CTRL_STEP::READY; + p_ctrl->data_type = p_ao->type; + p_ctrl->p_data = dc_create_data_ptr_by_type(p_ao->type); + if(nullptr == p_ctrl->p_data) { - LOG_E("self_ptl_cfg_init dc_create_data_ptr_by_type failed, type:%d", p_param->type); + LOG_E("self_ptl_cfg_init dc_create_data_ptr_by_type failed, type:%d", p_ao->type); return -1; } + p_cfg_data->ao_vec.push_back({p_ao, p_ctrl}); + + void *p_data = dc_create_data_ptr_by_type(p_ao->type); + if(nullptr == p_data) + { + LOG_E("self_ptl_cfg_init dc_create_data_ptr_by_type failed, type:%d", p_ao->type); + return -1; + } + p_cfg_data->ao_vec.back().vec_p_data.push_back(p_data); + + void *p_default_data = dc_create_data_ptr_by_type(p_ao->type); + if(nullptr == p_default_data) + { + LOG_E("self_ptl_cfg_init dc_create_data_ptr_by_type failed, type:%d", p_ao->type); + return -1; + } + p_cfg_data->ao_vec.back().vec_p_default_data.push_back(p_default_data); + } + + p_cfg_data->param_vec.reserve(p_cfg->param_vec.size() + 1); + for(uint32_t i = 0; i < p_cfg->param_vec.size(); i++) + { + stru_self_ptl_cfg_param *p_param = &p_cfg->param_vec[i]; + stru_signal_ctrl *p_ctrl = new stru_signal_ctrl; if(nullptr == p_ctrl) { @@ -563,7 +602,26 @@ LOCAL int self_ptl_cfg_init() return -1; } - p_cfg_data->param_vec.push_back({p_param, p_data, p_default_data, p_ctrl}); + p_cfg_data->param_vec.push_back({p_param, p_ctrl}); + + for(uint8_t i = 0; i < p_param->num; i++) + { + void *p_val_data = dc_create_data_ptr_by_type(p_param->type); + if(nullptr == p_val_data) + { + LOG_E("self_ptl_cfg_init dc_create_data_ptr_by_type failed, type:%d", p_param->type); + return -1; + } + p_cfg_data->param_vec.back().vec_p_data.push_back(p_val_data); + + void *p_default_val_data = dc_create_data_ptr_by_type(p_param->type); + if(nullptr == p_default_val_data) + { + LOG_E("self_ptl_cfg_init dc_create_data_ptr_by_type failed, type:%d", p_param->type); + return -1; + } + p_cfg_data->param_vec.back().vec_p_default_data.push_back(p_default_val_data); + } } return 0; @@ -584,13 +642,13 @@ void self_ptl_init() return; } - icp67_set_param_cfg_md5(p_icp67, p_self_cfg->param_md5); + icp67_set_ao_cfg_md5(p_icp67, p_self_cfg->ao_md5); stru_genneral_method *p_method = &g_self_ptl.method; - icp67_set_param_get_cb(&p_method->param_get_cb); - icp67_set_param_pop_out_cb(p_method->param_pop_out_cb); - icp67_set_param_set_cb(&p_method->param_set_cb); + icp67_set_ao_get_cb(&p_method->ao_get_cb); + icp67_set_ao_pop_out_cb(p_method->ao_pop_out_cb); + icp67_set_ao_set_cb(&p_method->ao_set_cb); icp67_set_iec_point_tbl_get_cb(&p_method->iec_point_tbl_get_cb); icp67_set_iec_point_tbl_pop_out_cb(p_method->iec_point_tbl_pop_out_cb); icp67_set_time_set_cb(&p_method->time_set_cb); @@ -657,7 +715,7 @@ void extract_saddr(const std::string &str, std::string ¶m, std::string &term } } -void self_ptl_signal_change_callback(std::string saddr, SIGNAL_CTRL_STEP step, uint8_t data_type, void *p_data) +void self_ptl_signal_change_callback(std::string saddr, SIGNAL_CTRL_STEP step, uint8_t data_type, uint8_t setting_zone, void *p_data) { std::string value = ""; if(p_data) @@ -700,15 +758,15 @@ void self_ptl_signal_change_callback(std::string saddr, SIGNAL_CTRL_STEP step, u { } - else if(signal_type == "param") + else if(signal_type == "ao") { if(step == SIGNAL_CTRL_STEP::DIRECT) { - if(g_self_ptl.method.param_set_cb) + if(g_self_ptl.method.ao_set_cb) { - for(uint32_t i = 0; i < p_self_cfg_data->param_vec.size(); i++) + for(uint32_t i = 0; i < p_self_cfg_data->ao_vec.size(); i++) { - stru_self_ptl_cfg_param_data *p = &p_self_cfg_data->param_vec.at(i); + stru_self_ptl_cfg_param_data *p = &p_self_cfg_data->ao_vec.at(i); if(p->p_param && p->p_param->base.saddr == saddr) { uint8_t temp[256] = {0}; @@ -716,15 +774,40 @@ void self_ptl_signal_change_callback(std::string saddr, SIGNAL_CTRL_STEP step, u p_data_info->data_addr = p->p_param->base.inf; p_data_info->data_type = p->p_param->type; p_data_info->data_len = dc_get_data_type_len(p->p_param->type); - std::string val = dc_get_signal_val(p->p_data, p->p_param->type); + std::string val = dc_get_signal_val(p->vec_p_data[0], p->p_param->type); strcpy((char *)p_data_info->data, val.c_str()); - g_self_ptl.method.param_set_cb(p_icp67, temp, 1); + g_self_ptl.method.ao_set_cb(p_icp67, temp, 1); break; } } } } } + else if(signal_type == "param") + { + if(step == SIGNAL_CTRL_STEP::DIRECT) + { + // if(g_self_ptl.method.param_set_cb) + // { + // for(uint32_t i = 0; i < p_self_cfg_data->param_vec.size(); i++) + // { + // stru_self_ptl_cfg_param_data *p = &p_self_cfg_data->param_vec.at(i); + // if(p->p_param && p->p_param->base.saddr == saddr) + // { + // uint8_t temp[256] = {0}; + // stru_ti_1_2_data_info *p_data_info = (stru_ti_1_2_data_info *)temp; + // p_data_info->data_addr = p->p_param->base.inf; + // p_data_info->data_type = p->p_param->type; + // p_data_info->data_len = dc_get_data_type_len(p->p_param->type); + // std::string val = dc_get_signal_val(p->vec_p_data[setting_zone], p->p_param->type); + // strcpy((char *)p_data_info->data, val.c_str()); + // g_self_ptl.method.param_set_cb(p_icp67, temp, 1); + // break; + // } + // } + // } + } + } } LOCAL float safeStringToFloat(const std::string& str) @@ -755,8 +838,6 @@ int self_ptl_do_signal_out(stru_app *p_app) goto ERR; } - // LOG_I("***********st_info_size %d", p_app_cfg->st_info_vec.size()); - for(uint32_t i = 0; i < p_app_cfg_data->st_vec.size(); i++) { p = &p_app_cfg_data->st_vec.at(i); @@ -813,6 +894,26 @@ int self_ptl_do_signal_out(stru_app *p_app) goto ERR; } + for(uint32_t i = 0; i < p_app_cfg_data->ao_vec.size(); i++) + { + stru_self_ptl_cfg_param_data *p_ao = &p_app_cfg_data->ao_vec.at(i); + if(p_ao && p_ao->p_param) + { + stru_signal_param param; + param.min = safeStringToFloat(p_ao->p_param->min); + param.max = safeStringToFloat(p_ao->p_param->max); + param.step = safeStringToFloat(p_ao->p_param->step); + param.unit = p_ao->p_param->unit; + + ret |= dc_signal_ao(p_ao->p_param->base.saddr, p_ao->p_param->base.desc, p_ao->p_param->type, param, SIGNAL_CTRL_TYPE::SBO_NORMAL, p_ao->vec_p_data[0], p_ao->vec_p_default_data[0], self_ptl_signal_change_callback); + } + } + + if(ret != 0) + { + goto ERR; + } + for(uint32_t i = 0; i < p_app_cfg_data->param_vec.size(); i++) { stru_self_ptl_cfg_param_data *p_param = &p_app_cfg_data->param_vec.at(i); @@ -822,10 +923,11 @@ int self_ptl_do_signal_out(stru_app *p_app) param.min = safeStringToFloat(p_param->p_param->min); param.max = safeStringToFloat(p_param->p_param->max); param.step = safeStringToFloat(p_param->p_param->step); - param.default_value = p_param->p_param->default_value; param.unit = p_param->p_param->unit; + + // ret(saddr, p(saddr, p->name, p->type, p->p_data); - ret |= dc_signal_param(p_param->p_param->base.saddr, p_param->p_param->base.desc, p_param->p_param->type, param, SIGNAL_CTRL_TYPE::SBO_NORMAL, p_param->p_data, self_ptl_signal_change_callback); + ret |= dc_signal_param(p_param->p_param->base.saddr, p_param->p_param->base.desc, p_param->p_param->type, param, SIGNAL_CTRL_TYPE::SBO_NORMAL, p_param->vec_p_data, p_param->vec_p_default_data, self_ptl_signal_change_callback); } } @@ -845,12 +947,6 @@ int app_self_ptl_init1(void *arg) { stru_app *p_app = (stru_app *)arg; - // if(0 != parse_cfg_files()) - // { - // MY_LOG_E("self ptl parse_cfg_files failed"); - // return -1; - // } - self_ptl_cfg_init(); self_ptl_init(); diff --git a/src/system/libweb_server/src/ws_method.cpp b/src/system/libweb_server/src/ws_method.cpp index 15fbd18..5eaa01e 100644 --- a/src/system/libweb_server/src/ws_method.cpp +++ b/src/system/libweb_server/src/ws_method.cpp @@ -9,7 +9,9 @@ typedef struct std::string desc; uint8_t data_type; uint8_t ctrl_type; - void *p_data; + // void *p_data; + std::vector vec_p_data; + std::vector vec_p_default_data; stru_signal_ctrl *p_ctrl; stru_signal_param *p_param; }stru_ws_signal; @@ -17,6 +19,7 @@ typedef struct LOCAL std::vector g_ws_out_signals; LOCAL std::vector g_ws_in_signals; LOCAL std::vector g_ws_yk_signals; +LOCAL std::vector g_ws_ao_signals; LOCAL std::vector g_ws_param_signals; @@ -48,13 +51,16 @@ void add_signal(const std::string& saddr, const std::string& signal_type) return; } - p_signals->push_back({saddr, "", 0, 0, nullptr, nullptr, nullptr}); + p_signals->reserve(p_signals->size() + 1); + p_signals->push_back({saddr, "", 0, 0}); p = &p_signals->back(); - if(0 != dc_get_out_signal_info(saddr, p->desc, p->data_type, &p->p_data)) + if(0 != dc_get_out_signal_info(saddr, p->desc, p->data_type, p->vec_p_data)) { LOG_E("add_signals: dc_get_out_signal_info failed, saddr = %s", saddr.c_str()); + p->vec_p_data.clear(); + p->vec_p_default_data.clear(); p_signals->pop_back(); return; } @@ -69,12 +75,15 @@ void add_signal(const std::string& saddr, const std::string& signal_type) return; } - p_signals->push_back({saddr, "", 0, 0, nullptr, nullptr, nullptr}); + p_signals->push_back({saddr, "", 0, 0}); p = &p_signals->back(); - if(0 != dc_get_in_signal_info(saddr, p->desc, p->data_type, &p->p_data)) + if(0 != dc_get_in_signal_info(saddr, p->desc, p->data_type, p->vec_p_data)) { LOG_E("add_signals: dc_get_in_signal_info failed, saddr = %s", saddr.c_str()); + + p->vec_p_data.clear(); + p->vec_p_default_data.clear(); p_signals->pop_back(); return; } @@ -88,17 +97,19 @@ void add_signal(const std::string& saddr, const std::string& signal_type) { LOG_E("add_signals: signal is already exist, saddr = %s", saddr.c_str()); return; - } + } - p_signals->push_back({saddr, "", 0, 0, nullptr, nullptr, nullptr}); + p_signals->push_back({saddr, "", 0, 0}); p_signals->back().p_ctrl = new stru_signal_ctrl; p = &p_signals->back(); - if(0 != dc_get_yk_signal_info(saddr, p->desc, p->data_type, p->ctrl_type, &p->p_data)) + if(0 != dc_get_yk_signal_info(saddr, p->desc, p->data_type, p->ctrl_type, p->vec_p_data)) { LOG_E("add_signals: dc_get_yk_signal_info failed, saddr = %s", saddr.c_str()); delete p->p_ctrl; + p->vec_p_data.clear(); + p->vec_p_default_data.clear(); p_signals->pop_back(); return; } @@ -112,6 +123,51 @@ void add_signal(const std::string& saddr, const std::string& signal_type) LOG_E("add_signals: dc_create_data_ptr_by_type failed, saddr = %s, data_type = %d", saddr.c_str(), p->data_type); delete p->p_ctrl; + p->vec_p_data.clear(); + p->vec_p_default_data.clear(); + p_signals->pop_back(); + return; + } + } + else if(signal_type == "ao") + { + p_signals = &g_ws_ao_signals; + + if(0 == signal_is_exist(saddr, g_ws_ao_signals)) + { + LOG_E("add_signals: signal is already exist, saddr = %s", saddr.c_str()); + return; + } + + p_signals->push_back({saddr, "", 0, 0}); + p_signals->back().p_ctrl = new stru_signal_ctrl; + p_signals->back().p_param = new stru_signal_param; + p = &p_signals->back(); + + if(0 != dc_get_ao_siganl_info(saddr, p->desc, p->data_type, *p->p_param, p->ctrl_type, p->vec_p_data, p->vec_p_default_data)) + { + LOG_E("add_signals: dc_get_ao_siganl_info failed, saddr = %s", saddr.c_str()); + + delete p->p_ctrl; + delete p->p_param; + p->vec_p_data.clear(); + p->vec_p_default_data.clear(); + p_signals->pop_back(); + return; + } + + p->p_ctrl->type = p->ctrl_type; + p->p_ctrl->step = SIGNAL_CTRL_STEP::READY; + p->p_ctrl->data_type = p->data_type; + p->p_ctrl->p_data = dc_create_data_ptr_by_type(p->data_type); + if(nullptr == p->p_ctrl->p_data) + { + LOG_E("add_signals: dc_create_data_ptr_by_type failed, saddr = %s, data_type = %d", saddr.c_str(), p->data_type); + + delete p->p_ctrl; + delete p->p_param; + p->vec_p_data.clear(); + p->vec_p_default_data.clear(); p_signals->pop_back(); return; } @@ -125,17 +181,19 @@ void add_signal(const std::string& saddr, const std::string& signal_type) LOG_E("add_signals: signal is already exist, saddr = %s", saddr.c_str()); return; } - p_signals->push_back({saddr, "", 0, 0, nullptr, nullptr, nullptr}); + p_signals->push_back({saddr, "", 0, 0}); p_signals->back().p_ctrl = new stru_signal_ctrl; p_signals->back().p_param = new stru_signal_param; p = &p_signals->back(); - if(0 != dc_get_param_signal_info(saddr, p->desc, p->data_type, *p->p_param, p->ctrl_type, &p->p_data)) + if(0 != dc_get_param_signal_info(saddr, p->desc, p->data_type, *p->p_param, p->ctrl_type, p->vec_p_data, p->vec_p_default_data)) { LOG_E("add_signals: dc_get_param_signal_info failed, saddr = %s", saddr.c_str()); delete p->p_ctrl; delete p->p_param; + p->vec_p_data.clear(); + p->vec_p_default_data.clear(); p_signals->pop_back(); return; } @@ -150,6 +208,8 @@ void add_signal(const std::string& saddr, const std::string& signal_type) delete p->p_ctrl; delete p->p_param; + p->vec_p_data.clear(); + p->vec_p_default_data.clear(); p_signals->pop_back(); return; } @@ -177,6 +237,10 @@ void del_signal(const std::string& saddr, const std::string& signal_type) { p_signals = &g_ws_yk_signals; } + else if(signal_type == "ao") + { + p_signals = &g_ws_ao_signals; + } else if(signal_type == "param") { p_signals = &g_ws_param_signals; @@ -201,6 +265,9 @@ void del_signal(const std::string& saddr, const std::string& signal_type) delete p_signal->p_param; } + p_signal->vec_p_data.clear(); + p_signal->vec_p_default_data.clear(); + p_signals->erase(p_signals->begin() + i); return; } @@ -209,7 +276,7 @@ void del_signal(const std::string& saddr, const std::string& signal_type) LOG_E("del_signal: not found saddr = %s", saddr.c_str()); } -void set_signal_data(const std::string& saddr, const std::string& signal_type, const std::string& signal_data) +void set_signal_data(const std::string& saddr, const std::string& signal_type, const uint8_t setting_zone, const std::string& signal_data) { std::vector *p_signals = nullptr; @@ -290,6 +357,53 @@ void set_signal_data(const std::string& saddr, const std::string& signal_type, c } } } + else if(signal_type == "ao") + { + p_signals = &g_ws_ao_signals; + + for(uint32_t i = 0; i < p_signals->size(); i++) + { + stru_ws_signal *p_signal = &p_signals->at(i); + if(p_signal->saddr == saddr) + { + if(p_signal->ctrl_type == SIGNAL_CTRL_TYPE::DIRECT_NORMAL) + { + if(0 != dc_signal_ao_set_val(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, (void *)signal_data.c_str())) + { + LOG_E("set_signal_data: dc_signal_ao_set_val direct failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str()); + return; + } + + LOG_I("saddr %s, direct, value %s success !!!", saddr.c_str(), signal_data.c_str()); + return; + } + else if(p_signal->ctrl_type == SIGNAL_CTRL_TYPE::SBO_NORMAL) + { + if(0 != dc_signal_ao_set_val(saddr, SIGNAL_CTRL_STEP::SELECT, *p_signal->p_ctrl, (void *)signal_data.c_str())) + { + LOG_E("set_signal_data: dc_signal_ao_set_val select failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str()); + return; + } + + LOG_I("saddr %s, select, value %s success !!!", saddr.c_str(), signal_data.c_str()); + + if(0 != dc_signal_ao_set_val(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, (void *)signal_data.c_str())) + { + LOG_E("set_signal_data: dc_signal_ao_set_val direct failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str()); + return; + } + + LOG_I("saddr %s, direct, value %s success !!!", saddr.c_str(), signal_data.c_str()); + return; + } + else + { + LOG_E("p_signal->ctrl_type is invalid, p_signal->ctrl_type = %d"); + return; + } + } + } + } else if(signal_type == "param") { p_signals = &g_ws_param_signals; @@ -301,7 +415,7 @@ void set_signal_data(const std::string& saddr, const std::string& signal_type, c { if(p_signal->ctrl_type == SIGNAL_CTRL_TYPE::DIRECT_NORMAL) { - if(0 != dc_signal_param_set_val(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, (void *)signal_data.c_str())) + if(0 != dc_signal_param_set_val(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, setting_zone, (void *)signal_data.c_str())) { LOG_E("set_signal_data: dc_signal_param_set_val direct failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str()); return; @@ -312,7 +426,7 @@ void set_signal_data(const std::string& saddr, const std::string& signal_type, c } else if(p_signal->ctrl_type == SIGNAL_CTRL_TYPE::SBO_NORMAL) { - if(0 != dc_signal_param_set_val(saddr, SIGNAL_CTRL_STEP::SELECT, *p_signal->p_ctrl, (void *)signal_data.c_str())) + if(0 != dc_signal_param_set_val(saddr, SIGNAL_CTRL_STEP::SELECT, *p_signal->p_ctrl, setting_zone, (void *)signal_data.c_str())) { LOG_E("set_signal_data: dc_signal_param_set_val select failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str()); return; @@ -320,7 +434,7 @@ void set_signal_data(const std::string& saddr, const std::string& signal_type, c LOG_I("saddr %s, select, value %s success !!!", saddr.c_str(), signal_data.c_str()); - if(0 != dc_signal_param_set_val(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, (void *)signal_data.c_str())) + if(0 != dc_signal_param_set_val(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, setting_zone, (void *)signal_data.c_str())) { LOG_E("set_signal_data: dc_signal_param_set_val direct failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str()); return; @@ -373,10 +487,11 @@ void ws_recv(const char* p_rx, uint16_t rx_len) cJSON *saddr = cJSON_GetObjectItem(root, "saddr"); cJSON *signal_type = cJSON_GetObjectItem(root, "signal_type"); cJSON *signal_data = cJSON_GetObjectItem(root, "signal_data"); + cJSON *setting_zone = cJSON_GetObjectItem(root, "setting_zone"); cJSON *curd = cJSON_GetObjectItem(root, "curd"); - std::string saddr_str = "", signal_type_str = "", signal_data_str = "", curd_str = ""; + std::string saddr_str = "", signal_type_str = "", signal_data_str = "", setting_zone_str = "", curd_str = ""; if(saddr && cJSON_IsString(saddr) && saddr->valuestring) { @@ -393,6 +508,11 @@ void ws_recv(const char* p_rx, uint16_t rx_len) signal_data_str = signal_data->valuestring; } + if(setting_zone && cJSON_IsString(setting_zone) && setting_zone->valuestring) + { + setting_zone_str = setting_zone->valuestring; + } + if(curd && cJSON_IsString(curd) && curd->valuestring) { curd_str = curd->valuestring; @@ -427,7 +547,7 @@ void ws_recv(const char* p_rx, uint16_t rx_len) } else if(0 == curd_str.compare("set")) { - set_signal_data(saddr_str, signal_type_str, signal_data_str); + set_signal_data(saddr_str, signal_type_str, atoi(setting_zone_str.c_str()), signal_data_str); } } @@ -435,10 +555,10 @@ void ws_recv(const char* p_rx, uint16_t rx_len) void ws_task() { - if(g_ws_out_signals.empty() && g_ws_in_signals.empty() && g_ws_yk_signals.empty() && g_ws_param_signals.empty()) - { - return; - } + // if(g_ws_out_signals.empty() && g_ws_in_signals.empty() && g_ws_yk_signals.empty() && g_ws_ao_signals.empty() && g_ws_param_signals.empty()) + // { + // return; + // } const char ctrl_type_str[][16] = {"NONE", "DIRECT_NORMAL", "SBO_NORMAL"}; @@ -467,7 +587,7 @@ void ws_task() cJSON_AddItemToObject(item, "desc", cJSON_CreateString(p_signal->desc.c_str())); cJSON_AddItemToObject(item, "type", cJSON_CreateString(dc_get_data_type_str_by_id(p_signal->data_type).c_str())); - std::string val = dc_get_signal_val(p_signal->p_data, p_signal->data_type); + std::string val = dc_get_signal_val(p_signal->vec_p_data[0], p_signal->data_type); cJSON_AddItemToObject(item, "val", cJSON_CreateString(val.c_str())); cJSON_AddItemToArray(out_arr, item); } @@ -489,7 +609,7 @@ void ws_task() cJSON_AddItemToObject(item, "saddr", cJSON_CreateString(p_signal->saddr.c_str())); cJSON_AddItemToObject(item, "desc", cJSON_CreateString(p_signal->desc.c_str())); cJSON_AddItemToObject(item, "type", cJSON_CreateString(dc_get_data_type_str_by_id(p_signal->data_type).c_str())); - std::string val = dc_get_signal_val(p_signal->p_data, p_signal->data_type); + std::string val = dc_get_signal_val(p_signal->vec_p_data[0], p_signal->data_type); cJSON_AddItemToObject(item, "val", cJSON_CreateString(val.c_str())); cJSON_AddItemToArray(in_arr, item); } @@ -510,12 +630,50 @@ void ws_task() cJSON_AddItemToObject(item, "saddr", cJSON_CreateString(p_signal->saddr.c_str())); cJSON_AddItemToObject(item, "desc", cJSON_CreateString(p_signal->desc.c_str())); cJSON_AddItemToObject(item, "type", cJSON_CreateString(dc_get_data_type_str_by_id(p_signal->data_type).c_str())); - std::string val = dc_get_signal_val(p_signal->p_data, p_signal->data_type); + std::string val = dc_get_signal_val(p_signal->vec_p_data[0], p_signal->data_type); cJSON_AddItemToObject(item, "val", cJSON_CreateString(val.c_str())); cJSON_AddItemToObject(item, "ctrl_type", cJSON_CreateString(ctrl_type_str[p_signal->ctrl_type])); cJSON_AddItemToArray(yk_arr, item); } + cJSON *ao_arr = cJSON_CreateArray(); + cJSON_AddItemToObject(root, "ao", ao_arr); + + for(uint32_t i = 0; i < g_ws_ao_signals.size(); i++) + { + stru_ws_signal *p_signal = &g_ws_ao_signals.at(i); + cJSON *item = cJSON_CreateObject(); + if(nullptr == item) + { + LOG_E("ws_task: cJSON_CreateObject failed"); + cJSON_Delete(root); + return; + } + + cJSON_AddItemToObject(item, "saddr", cJSON_CreateString(p_signal->saddr.c_str())); + cJSON_AddItemToObject(item, "desc", cJSON_CreateString(p_signal->desc.c_str())); + cJSON_AddItemToObject(item, "type", cJSON_CreateString(dc_get_data_type_str_by_id(p_signal->data_type).c_str())); + // std::string val = dc_get_signal_val(p_signal->vec_p_data[0], p_signal->data_type); + // cJSON_AddItemToObject(item, "val", cJSON_CreateString(val.c_str())); + cJSON_AddItemToObject(item, "ctrl_type", cJSON_CreateString(ctrl_type_str[p_signal->ctrl_type])); + if(p_signal->p_param) + { + cJSON_AddItemToObject(item, "min", cJSON_CreateString(std::to_string(p_signal->p_param->min).c_str())); + cJSON_AddItemToObject(item, "max", cJSON_CreateString(std::to_string(p_signal->p_param->max).c_str())); + cJSON_AddItemToObject(item, "step", cJSON_CreateString(std::to_string(p_signal->p_param->step).c_str())); + cJSON_AddItemToObject(item, "unit", cJSON_CreateString(p_signal->p_param->unit.c_str())); + // cJSON_AddItemToObject(item, "default", cJSON_CreateString(p_signal->p_param->default_value.c_str())); + } + + std::string val = dc_get_signal_val(p_signal->vec_p_data[0], p_signal->data_type); + cJSON_AddItemToObject(item, "val", cJSON_CreateString(val.c_str())); + std::string default_val = dc_get_signal_val(p_signal->vec_p_default_data[0], p_signal->data_type); + cJSON_AddItemToObject(item, "default_val", cJSON_CreateString(default_val.c_str())); + + cJSON_AddItemToArray(ao_arr, item); + } + + cJSON *param_arr = cJSON_CreateArray(); cJSON_AddItemToObject(root, "param", param_arr); @@ -533,8 +691,8 @@ void ws_task() cJSON_AddItemToObject(item, "saddr", cJSON_CreateString(p_signal->saddr.c_str())); cJSON_AddItemToObject(item, "desc", cJSON_CreateString(p_signal->desc.c_str())); cJSON_AddItemToObject(item, "type", cJSON_CreateString(dc_get_data_type_str_by_id(p_signal->data_type).c_str())); - std::string val = dc_get_signal_val(p_signal->p_data, p_signal->data_type); - cJSON_AddItemToObject(item, "val", cJSON_CreateString(val.c_str())); + // std::string val = dc_get_signal_val(p_signal->vec_p_data[0], p_signal->data_type); + // cJSON_AddItemToObject(item, "val", cJSON_CreateString(val.c_str())); cJSON_AddItemToObject(item, "ctrl_type", cJSON_CreateString(ctrl_type_str[p_signal->ctrl_type])); if(p_signal->p_param) { @@ -542,16 +700,29 @@ void ws_task() cJSON_AddItemToObject(item, "max", cJSON_CreateString(std::to_string(p_signal->p_param->max).c_str())); cJSON_AddItemToObject(item, "step", cJSON_CreateString(std::to_string(p_signal->p_param->step).c_str())); cJSON_AddItemToObject(item, "unit", cJSON_CreateString(p_signal->p_param->unit.c_str())); - cJSON_AddItemToObject(item, "default", cJSON_CreateString(p_signal->p_param->default_value.c_str())); - // if(p_signal->p_param->p_default) - // { - // cJSON_AddItemToObject(item, "default", cJSON_CreateString(dc_get_signal_val(p_signal->p_param->p_default, p_signal->data_type).c_str())); - // } - // else - // { - // cJSON_AddItemToObject(item, "default", cJSON_CreateString("")); - // } + // cJSON_AddItemToObject(item, "default", cJSON_CreateString(p_signal->p_param->default_value.c_str())); } + + for(uint32_t j = 0; j < p_signal->vec_p_data.size(); j++) + { + cJSON *setting_zone_item = cJSON_CreateObject(); + if(nullptr == setting_zone_item) + { + LOG_E("ws_task: cJSON_CreateObject failed"); + cJSON_Delete(root); + return; + } + + std::string setting_zone_str = std::to_string(j); + cJSON_AddItemToObject(setting_zone_item, "setting_zone", cJSON_CreateString(setting_zone_str.c_str())); + std::string val = dc_get_signal_val(p_signal->vec_p_data[j], p_signal->data_type); + cJSON_AddItemToObject(setting_zone_item, "val", cJSON_CreateString(val.c_str())); + std::string default_val = dc_get_signal_val(p_signal->vec_p_default_data[j], p_signal->data_type); + cJSON_AddItemToObject(setting_zone_item, "default_val", cJSON_CreateString(default_val.c_str())); + + cJSON_AddItemToArray(item, setting_zone_item); + } + cJSON_AddItemToArray(param_arr, item); } diff --git a/test/config/iec1014.xml b/test/config/iec1014.xml index 11c935c..fea0e67 100644 --- a/test/config/iec1014.xml +++ b/test/config/iec1014.xml @@ -18,7 +18,7 @@
- + @@ -35,5 +35,7 @@ + + \ No newline at end of file diff --git a/test/config/self_ptl.xml b/test/config/self_ptl.xml index b0457d2..41050c8 100644 --- a/test/config/self_ptl.xml +++ b/test/config/self_ptl.xml @@ -1,2987 +1,2988 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/test/file/MMS/prj.xml b/test/file/MMS/prj.xml index de18982..86e6a95 100644 --- a/test/file/MMS/prj.xml +++ b/test/file/MMS/prj.xml @@ -24,12 +24,15 @@ - + + + + + + \ No newline at end of file diff --git a/test/file/PARAM/param.xml b/test/file/PARAM/param.xml index ed35a27..5999332 100644 --- a/test/file/PARAM/param.xml +++ b/test/file/PARAM/param.xml @@ -1,13 +1,5 @@ - - - - - - - - - - - \ No newline at end of file + + + diff --git a/test/web_root/index.html b/test/web_root/index.html index b593ae9..56a2c37 100644 --- a/test/web_root/index.html +++ b/test/web_root/index.html @@ -65,14 +65,15 @@ +
@@ -123,6 +124,16 @@ +
+
AO 信号
+
+ + + +
#saddrdesc数据类型valctrl_typeminmaxstepunitdefault
+
+
+
PARAM 信号
@@ -145,6 +156,7 @@ out: document.getElementById('outBody'), in: document.getElementById('inBody'), yk: document.getElementById('ykBody'), + ao: document.getElementById('aoBody'), param: document.getElementById('paramBody') }; @@ -177,7 +189,7 @@ // 每次收到数据,直接清空对应表格,重新渲染 function parseData(root) { - const types = ['out', 'in', 'yk', 'param']; + const types = ['out', 'in', 'yk', 'ao', 'param']; types.forEach(type => { const arr = root[type]; const body = tableBodies[type]; @@ -208,6 +220,19 @@ if (type === 'yk') { html += `${item.ctrl_type || '-'}`; } + + // ao 增加完整参数列 + if (type === 'ao') { + html += ` + ${item.ctrl_type || '-'} + ${item.min || '-'} + ${item.max || '-'} + ${item.step || '-'} + ${item.unit || '-'} + ${item.default || '-'} + `; + } + // param 增加完整参数列 if (type === 'param') { html += `