diff --git a/release/inc/myMms_m.h b/release/inc/myMms_m.h index b61c18c..f78417b 100644 --- a/release/inc/myMms_m.h +++ b/release/inc/myMms_m.h @@ -11,7 +11,9 @@ extern "C" { #define MY_GET_DATA_WITH_TYPE(p, type) (*(type *)(p)) #endif - +#define MMS_M_REASON_ALL_CALL 64 // 总召遥信遥测参数 +#define MMS_M_REASON_READ_AO 65 // 读取参数 +#define MMS_M_REASON_READ_PARAM 66 // 读取定值 enum { @@ -79,6 +81,7 @@ typedef struct MMS_STR desc; MMS_REF reference; void *p_value; + int set_zone; // 定值区 stru_mms_m_time time; }stru_mms_m_out_value; @@ -157,10 +160,13 @@ int mms_m_out_get_connect_status(int fd, mms_m_out_status_cb p_func); int mms_m_out_debug_print_swicth(int id, int debug_print_flag); -int mms_m_out_do_set_yk_or_param(stru_mms_m_event *p_event); +int mms_m_out_do_set_yk(stru_mms_m_event *p_event); -int mms_m_out_read_params(int app_fd); -int mms_m_out_read_param(int app_fd, const char *param_name); + + +int mms_m_out_read_ao_or_params(int app_fd, uint8_t type, const char *saddr); + +int mms_m_out_bind_param_zone_signal(int app_fd, const char *zone_saddr); int mms_m_out_get_value(int app_fd, mms_m_out_value_cb p_func); char *mms_m_out_reason_str(int reason); diff --git a/src/protocol/libmms_m/inc/mms_m.h b/src/protocol/libmms_m/inc/mms_m.h index d0751d3..2b898c0 100644 --- a/src/protocol/libmms_m/inc/mms_m.h +++ b/src/protocol/libmms_m/inc/mms_m.h @@ -50,10 +50,10 @@ #define LOG_E(fmt, ...) LOG(COLOR_RED, "ERROR", fmt, ##__VA_ARGS__) -#define MMS_M_THREAD_RUN_TM 100 //线程运行间隔时间 100ms +#define MMS_M_THREAD_RUN_TM 100*3 //线程运行间隔时间 100ms #define MMS_M_TIMER_T0 (120 * (MMS_M_THREAD_RUN_TM * 10 / 1000)) // 定时器T0 120秒 #define MMS_M_TIMER_T1 (60 * (MMS_M_THREAD_RUN_TM * 10 / 1000)) // 定时器T1 60秒 -#define MMS_M_TIMER_T2 (15 * (MMS_M_THREAD_RUN_TM * 10 / 1000)) // 定时器T2 15秒 +#define MMS_M_TIMER_T2 (30 * (MMS_M_THREAD_RUN_TM * 10 / 1000)) // 定时器T2 30秒 #define MMS_M_TIMER_T3 (20 * (MMS_M_THREAD_RUN_TM * 10 / 1000)) // 定时器T3 20秒 @@ -177,6 +177,9 @@ typedef struct std::string ied_name; // ied名称 MmsValue *param_zone; // 参数定值区 MmsValue *set_confirm; // 设置确认 + + MMS_STR zone_saddr; // 关联的定值区信号saddr(如ao.0) + int current_zone; // 当前定值区号 stru_mms_m_run run; // 运行时数据结构 diff --git a/src/protocol/libmms_m/src/mms_m.cpp b/src/protocol/libmms_m/src/mms_m.cpp index 7cf02dc..a2bdbab 100644 --- a/src/protocol/libmms_m/src/mms_m.cpp +++ b/src/protocol/libmms_m/src/mms_m.cpp @@ -13,8 +13,7 @@ // #include "conversions.h" -#define MMS_M_REASON_ALL_CALL 64 -#define MMS_M_REASON_READ_PARAM 65 + #define MMS_M_RECONNECT_INTERVAL 60 // seconds static const std::string g_sgcb_edit_sg = "LLN0.SGCB.EditSG"; @@ -37,6 +36,7 @@ void Conversions_msTimeToGeneralizedTime(unsigned long msTime, unsigned char* bu } #endif +// static void sleep_ms(uint32_t ms) { struct timespec rqtp; @@ -209,7 +209,7 @@ static int mms_m_get_mmsValue(MmsValue *mms_value, uint8_t &type, void *p_val) strcpy((char *)p_val, MmsValue_toString(mms_value)); break; default: - LOG_E("mms_m_get_mmsValue Failed to read value (error code: %i)\n", MmsValue_getDataAccessError(mms_value)); + LOG_E("mms_m_get_mmsValue Failed to read value %d\n", mms_type); return -1; } @@ -286,6 +286,101 @@ static int mms_m_param_value_sync(stru_point_item &item, stru_mms_m_event &event return 0; } +static void mms_m_send_read_ao(stru_mms_m_obj &obj, stru_mms_m_event &event) +{ + IedClientError err; + MmsValue *p_value = NULL; + + stru_mms_m_out_value out_val; + stru_point_item *p_item = NULL; + + // When saddr is empty, read ALL AO values; otherwise match specific saddr + bool match_all = (strlen(event.saddr) == 0); + for(int i = 0; i < obj.p_cfg->point.ao_num; i++) + { + if(match_all) + { + p_item = &obj.p_cfg->point.p_ao[i]; + } + else if(obj.p_cfg->point.p_ao && 0 == strcmp(event.saddr, obj.p_cfg->point.p_ao[i].saddr)) + { + p_item = &obj.p_cfg->point.p_ao[i]; + } + else + { + continue; + } + + if(NULL == (p_value = IedConnection_readObject(obj.run.con, &err, p_item->reference, (FunctionalConstraint)p_item->fc))) + { + LOG_E("%s: saddr %s, ref %s read err:%s(%d)\n", + obj.cfg_path.c_str(), p_item->saddr, p_item->reference, mms_m_err_str(err), err); + continue; + } + + if(MMS_M_DEBUG_PRINT_ON == obj.debug_print_flag) + { + mms_m_show_MmsValue(p_value, &p_item->type); + } + + if(0 != mms_m_get_mmsValue(p_value, p_item->type, p_item->value.p_val[0])) + { + LOG_E("get mms value failed"); + MmsValue_delete(p_value); + continue; + } + + mms_m_get_local_time(out_val.time); + out_val.p_value = p_item->value.p_val[0]; + out_val.type = p_item->type; + out_val.quality = 0; + + snprintf(out_val.name, sizeof(out_val.name), "%s", p_item->saddr); + snprintf(out_val.desc, sizeof(out_val.desc), "%s", p_item->desc); + snprintf(out_val.reference, sizeof(out_val.reference), "%s", p_item->reference); + out_val.reason = MMS_M_REASON_READ_AO; // call ao + out_val.app_fd = obj.obj_fd; + + mms_m_put_value(obj, out_val); + + // Check if this is the zone signal and detect zone change + if (strlen(obj.zone_saddr) > 0 && 0 == strcmp(obj.zone_saddr, p_item->saddr)) + { + int new_zone = 0; + switch (p_item->type) + { + case MMS_INTEGER: + new_zone = MY_GET_DATA_WITH_TYPE(p_item->value.p_val[0], int32_t); + break; + case MMS_UNSIGNED: + new_zone = (int)MY_GET_DATA_WITH_TYPE(p_item->value.p_val[0], uint32_t); + break; + default: + break; + } + if (new_zone > 0 && (new_zone) != obj.current_zone) + { + LOG_I("%s: zone changed %d -> %d, trigger param re-read", obj.cfg_path.c_str(), obj.current_zone, new_zone); + obj.current_zone = new_zone; + + stru_mms_m_event param_event; + memset(¶m_event, 0, sizeof(stru_mms_m_event)); + param_event.ctrl_type = _MMS_M_EVENT_PARAM_READ; + mms_m_push_event(obj, param_event); + } + else if (obj.current_zone == 0 && new_zone > 0 && (new_zone) != obj.current_zone) + { + obj.current_zone = new_zone; + LOG_I("%s: init zone=%d from %s", obj.cfg_path.c_str(), obj.current_zone, p_item->saddr); + } + } + + MmsValue_delete(p_value); + } + +} + + static int mms_m_send_ao_write(stru_mms_m_obj &obj, stru_mms_m_event &event) { stru_point_item *p_item = NULL; @@ -336,17 +431,73 @@ static int mms_m_send_ao_write(stru_mms_m_obj &obj, stru_mms_m_event &event) return 0; } -static void demo_sg_cb(int fd, const char *ld_name, - int act_sg, int num_sg, int err) +static void mms_m_send_read_param(stru_mms_m_obj &obj, stru_mms_m_event &event) { - if (IED_ERROR_OK != err) - { - LOG_E("read SG info failed: %s, err=%d", ld_name, err); -/** 定值组信息读取回调 */ - return; - } + MmsValue *p_value = NULL; + stru_mms_m_out_value out_val; + stru_point_item *p_item = NULL; + IedClientError err; - LOG_I("%s: active SG=%d, total SG=%d", ld_name, act_sg, num_sg); + bool match_all = (strlen(event.saddr) == 0); + + int act_sg = obj.current_zone; + + LOG_I("%s: read params with zone=%d (bound=%s)", obj.cfg_path.c_str(), act_sg, + strlen(obj.zone_saddr) > 0 ? obj.zone_saddr : "unbound"); + + for(int i = 0; i < obj.p_cfg->point.param_num; i++) + { + if(match_all) + { + p_item = &obj.p_cfg->point.p_param[i]; + } + else if(obj.p_cfg->point.p_param && 0 == strcmp(event.saddr, obj.p_cfg->point.p_param[i].saddr)) + { + p_item = &obj.p_cfg->point.p_param[i]; + } + else + { + continue; + } + + if(NULL == (p_value = IedConnection_readObject(obj.run.con, &err, p_item->reference, (FunctionalConstraint)p_item->fc))) + { + LOG_E("%s: saddr %s, ref %s read err:%s(%d)\n", + obj.cfg_path.c_str(), p_item->saddr, p_item->reference, mms_m_err_str(err), err); + continue; + } + + if(MMS_M_DEBUG_PRINT_ON == obj.debug_print_flag) + { + mms_m_show_MmsValue(p_value, &p_item->type); + } + + // temp buffer to avoid polluting p_val[0] (== vec[0] after signal replace) + uint8_t tmp_val[MMS_M_DATA_STRING_LEN] = {0}; + if(0 != mms_m_get_mmsValue(p_value, p_item->type, tmp_val)) + { + LOG_E("get mms value failed, ref %s", p_item->reference); + MmsValue_delete(p_value); + continue; + } + + mms_m_get_local_time(out_val.time); + out_val.p_value = tmp_val; + out_val.type = p_item->type; + out_val.quality = 0; + + snprintf(out_val.name, sizeof(out_val.name), "%s", p_item->saddr); + snprintf(out_val.desc, sizeof(out_val.desc), "%s", p_item->desc); + snprintf(out_val.reference, sizeof(out_val.reference), "%s", p_item->reference); + out_val.reason = MMS_M_REASON_READ_PARAM; // call param + out_val.app_fd = obj.obj_fd; + out_val.set_zone = act_sg; + + mms_m_put_value(obj, out_val); + + MmsValue_delete(p_value); + + } } static int mms_m_send_param_write(stru_mms_m_obj &obj, stru_mms_m_event &event) @@ -369,7 +520,6 @@ static int mms_m_send_param_write(stru_mms_m_obj &obj, stru_mms_m_event &event) return -1; } - mms_m_read_sg_info(obj.obj_fd, p_item->ldev, demo_sg_cb); std::string ref = p_item->reference; size_t pos = ref.find("/"); @@ -446,60 +596,6 @@ static int mms_m_send_param_write(stru_mms_m_obj &obj, stru_mms_m_event &event) return 0; } -static void mms_m_send_read_ao(stru_mms_m_obj &obj, stru_mms_m_event &event) -{ - IedClientError err; - MmsValue *p_value = NULL; - - stru_mms_m_out_value out_val; - stru_point_item *p_item = NULL; - - for(int i = 0; i < obj.p_cfg->point.ao_num; i++) - { - if(obj.p_cfg->point.p_ao && 0 == strcmp(event.saddr, obj.p_cfg->point.p_ao[i].saddr)) - { - p_item = &obj.p_cfg->point.p_ao[i]; - } - else - { - continue; - } - - if(NULL == (p_value = IedConnection_readObject(obj.run.con, &err, p_item->reference, (FunctionalConstraint)p_item->fc))) - { - LOG_E("%s: saddr %s, ref %s read err:%s(%d)\n", - obj.cfg_path.c_str(), p_item->saddr, p_item->reference, mms_m_err_str(err), err); - continue; - } - - if(MMS_M_DEBUG_PRINT_ON == obj.debug_print_flag) - { - mms_m_show_MmsValue(p_value, &p_item->type); - } - - if(0 != mms_m_get_mmsValue(p_value, p_item->type, p_item->value.p_val[0])) - { - LOG_E("get mms value failed"); - MmsValue_delete(p_value); - continue; - } - - mms_m_get_local_time(out_val.time); - out_val.p_value = p_item->value.p_val[0]; - out_val.type = p_item->type; - out_val.quality = 0; - - snprintf(out_val.name, sizeof(out_val.name), "%s", p_item->saddr); - snprintf(out_val.desc, sizeof(out_val.desc), "%s", p_item->desc); - snprintf(out_val.reference, sizeof(out_val.reference), "%s", p_item->reference); - out_val.reason = MMS_M_REASON_READ_PARAM; // call param - out_val.app_fd = obj.obj_fd; - - mms_m_put_value(obj, out_val); - - MmsValue_delete(p_value); - } -} static void mms_m_command_termination_handler(void *parameter, ControlObjectClient connection) { @@ -767,7 +863,6 @@ static void mms_m_send_call_all(stru_mms_m_obj &obj) { {&obj.p_cfg->point.st_num, obj.p_cfg->point.p_st}, {&obj.p_cfg->point.mx_num, obj.p_cfg->point.p_mx}, - {&obj.p_cfg->point.ao_num, obj.p_cfg->point.p_ao}, }; IedClientError err; @@ -845,6 +940,7 @@ static void mms_m_do_send(stru_mms_m_obj &obj) mms_m_send_set_callback(event, mms_m_send_ao_write(obj, event)); break; case _MMS_M_EVENT_PARAM_READ: + mms_m_send_read_param(obj, event); break; case _MMS_M_EVENT_PARAM_WRITE: mms_m_send_set_callback(event, mms_m_send_param_write(obj, event)); @@ -1553,6 +1649,21 @@ static void mms_m_do_call_GI(void *arg) mms_m_timer_start(p_obj->run.timer[_MMS_M_TIMER_T1]); } +static void mms_m_do_call_all_ao_param(void *arg) +{ + stru_mms_m_obj *p_obj = (stru_mms_m_obj *)arg; + if(NULL == p_obj) + { + LOG_E("mms_m_do_call_all_ao_param p_obj is NULL"); + return; + } + + mms_m_out_read_ao_or_params(p_obj->obj_fd, _MMS_M_EVENT_AO_READ, nullptr); + mms_m_out_read_ao_or_params(p_obj->obj_fd, _MMS_M_EVENT_PARAM_READ, nullptr); + + mms_m_timer_start(p_obj->run.timer[_MMS_M_TIMER_T2]); +} + static void mms_m_timer_init(stru_mms_m_obj &obj) { stru_mms_m_timer *p_timer = obj.run.timer; @@ -1574,8 +1685,8 @@ static void mms_m_timer_init(stru_mms_m_obj &obj) p_timer[_MMS_M_TIMER_T2].tmout = MMS_M_TIMER_T2; - p_timer[_MMS_M_TIMER_T2].arg = NULL; - p_timer[_MMS_M_TIMER_T2].p_func = NULL; + p_timer[_MMS_M_TIMER_T2].arg = &obj; + p_timer[_MMS_M_TIMER_T2].p_func = mms_m_do_call_all_ao_param; p_timer[_MMS_M_TIMER_T3].tmout = MMS_M_TIMER_T3; p_timer[_MMS_M_TIMER_T3].arg = NULL; @@ -1908,7 +2019,7 @@ int mms_m_out_debug_print_swicth(int app_fd, int debug_print_flag) return 0; } -int mms_m_out_do_set_yk_or_param(stru_mms_m_event *p_event) +int mms_m_out_do_set_yk(stru_mms_m_event *p_event) { if(NULL == p_event) { @@ -1942,7 +2053,7 @@ int mms_m_out_do_set_yk_or_param(stru_mms_m_event *p_event) return -1; } -int mms_m_out_read_params(int app_fd) +int mms_m_out_bind_param_zone_signal(int app_fd, const char *zone_saddr) { if(g_mms_m_obj_map.find(app_fd) == g_mms_m_obj_map.end()) { @@ -1952,30 +2063,44 @@ int mms_m_out_read_params(int app_fd) stru_mms_m_obj &obj = *g_mms_m_obj_map[app_fd]; - stru_mms_m_event event; - memset(&event, 0, sizeof(stru_mms_m_event)); + if(nullptr == zone_saddr || strlen(zone_saddr) == 0) + { + LOG_E("zone_saddr is NULL or empty\n"); + return -1; + } - event.ctrl_type = _MMS_M_EVENT_AO_READ; - mms_m_push_event(obj, event); + strncpy(obj.zone_saddr, zone_saddr, sizeof(obj.zone_saddr)); + obj.current_zone = 0; + + LOG_I("%s: bind zone signal %s", obj.cfg_path.c_str(), zone_saddr); return 0; } -int mms_m_out_read_param(int app_fd, const char *param_name) +int mms_m_out_read_ao_or_params(int app_fd, uint8_t type, const char *saddr) { if(g_mms_m_obj_map.find(app_fd) == g_mms_m_obj_map.end()) { LOG_E("IED with id %d not found\n", app_fd); return -1; } + + if(type != _MMS_M_EVENT_AO_READ && type != _MMS_M_EVENT_PARAM_READ) + { + LOG_E("type %d is not supported", type); + return -1; + } stru_mms_m_obj &obj = *g_mms_m_obj_map[app_fd]; stru_mms_m_event event; memset(&event, 0, sizeof(stru_mms_m_event)); - event.ctrl_type = _MMS_M_EVENT_AO_READ; - strncpy(event.saddr, param_name, sizeof(param_name)); + event.ctrl_type = type; + if(nullptr != saddr) + { + strncpy(event.saddr, saddr, sizeof(event.saddr)); + } mms_m_push_event(obj, event); return 0; @@ -1983,6 +2108,8 @@ int mms_m_out_read_param(int app_fd, const char *param_name) + + int mms_m_out_get_value(int fd, mms_m_out_value_cb p_func) { if(g_mms_m_obj_map.find(fd) == g_mms_m_obj_map.end()) diff --git a/src/system/libdatacenter/src/dc_param.cpp b/src/system/libdatacenter/src/dc_param.cpp index c733bb2..83402c5 100644 --- a/src/system/libdatacenter/src/dc_param.cpp +++ b/src/system/libdatacenter/src/dc_param.cpp @@ -294,6 +294,10 @@ static int dc_param_register_signals(const std::string ¶m_path, if (!vec_p_data.empty() && vec_p_data.size() == vec_p_default_data.size()) { + printf("[REG_PARAM] saddr=%s num=%d\n", saddr, num); + for (size_t _i = 0; _i < vec_p_data.size(); _i++) { + printf(" zone %zu: val=%s def=%s\n", _i, dc_get_signal_val(vec_p_data[_i], data_type).c_str(), dc_get_signal_val(vec_p_default_data[_i], data_type).c_str()); + } dc_signal_param(saddr, desc, data_type, SIGNAL_CTRL_TYPE::SBO_NORMAL, vec_p_data.data(), vec_p_default_data.data(), num, nullptr); diff --git a/src/system/libdatacenter/src/dc_signal.cpp b/src/system/libdatacenter/src/dc_signal.cpp index f4b2e65..b9087fa 100644 --- a/src/system/libdatacenter/src/dc_signal.cpp +++ b/src/system/libdatacenter/src/dc_signal.cpp @@ -432,25 +432,29 @@ LOCAL bool dc_signal_param_add_check(stru_signal *p_signal, const std::string &d if(p_signal->desc != desc) { p_signal->desc = desc; + printf("desc=%s\n", p_signal->desc.c_str()); change = true; } if(p_signal->data_type != data_type) { p_signal->data_type = data_type; + printf("data_type=%d\n", p_signal->data_type); change = true; } - if(p_signal->ctrl_type != ctrl_type) - { - p_signal->ctrl_type = ctrl_type; - change = true; - } + // if(p_signal->ctrl_type != ctrl_type) + // { + // p_signal->ctrl_type = ctrl_type; + // printf("ctrl_type=%d\n", p_signal->ctrl_type); + // change = true; + // } for(size_t i = 0; i < num; i++) { if(0 != dc_data_compare(p_signal->data_type, p_default_data[i], p_signal->vec_p_default_data[i])) { + printf(" zone %d: val=%s def=%s, %p, %p\n", i+1, dc_get_signal_val(p_signal->vec_p_data[i], p_signal->data_type).c_str(), dc_get_signal_val(p_signal->vec_p_default_data[i], p_signal->data_type).c_str(), p_signal->vec_p_data[i], p_signal->vec_p_default_data[i]); change = true; } } @@ -1101,14 +1105,16 @@ int dc_signal_ao(const std::string &saddr, const std::string &desc, uint8_t data stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_ao); if(p_signal != nullptr && !p_signal->vec_p_data.empty() && !p_signal->vec_p_default_data.empty() && nullptr != p_signal->vec_p_data[0] && nullptr != p_signal->vec_p_default_data[0]) { + // Always copy old value to new pointer when data type matches + if(p_signal->data_type == data_type) + { + dc_set_signal_val(p_data, data_type, p_signal->vec_p_data[0]); + } + if(true == dc_signal_ao_add_check(p_signal, desc, data_type, ctrl_type, 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); @@ -1281,10 +1287,12 @@ int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t d return -1; } + printf("[SIGNAL_PARAM] saddr=%s data_num=%d\n", saddr.c_str(), data_num); for(int i = 0; i < data_num; i++) { if(p_data[i] == nullptr || p_default_data[i] == nullptr) { + printf("[SIGNAL_PARAM_ERR] saddr=%s i=%d p_data=%p p_def=%p\n", saddr.c_str(), i, (void*)p_data[i], (void*)p_default_data[i]); MY_LOG_E("p_data[%d] or p_default_data[%d] is nullptr", i, i); return -1; } @@ -1294,17 +1302,28 @@ int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t d stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param); if(p_signal != nullptr) { - // dc_set_signal_val(p_data, data_type, p_signal->p_data); - if(true == dc_signal_param_add_check(p_signal, desc, data_type, ctrl_type, p_default_data, data_num)) + // Always copy old values to new pointers when data type matches + if(p_signal->data_type == data_type) { + size_t copy_num = (data_num < p_signal->vec_p_data.size()) ? data_num : p_signal->vec_p_data.size(); + for(size_t i = 0; i < copy_num; i++) + { + dc_set_signal_val(p_data[i], data_type, p_signal->vec_p_data[i]); + } + } + + // dc_set_signal_val(p_data, data_type, p_signal->p_data); + bool check_result = dc_signal_param_add_check(p_signal, desc, data_type, ctrl_type, p_default_data, data_num); + printf("[SIGNAL_PARAM_REPLACE] saddr=%s add_check=%d old_size=%d new_size=%d\n", + saddr.c_str(), (int)check_result, (int)p_signal->vec_p_data.size(), data_num); + if (check_result) + { + printf("[SIGNAL_PARAM_REPLACE] add_check=true -> metadata changed, cfg_change set!\n"); dc_set_param_cfg_change(true); } else { - for(size_t i = 0; i < data_num; i++) - { - dc_set_signal_val(p_data[i], data_type, p_signal->vec_p_data[i]); - } + printf("[SIGNAL_PARAM_REPLACE] add_check=false -> metadata unchanged\n"); } for(size_t i = 0; i < data_num; i++) @@ -1456,6 +1475,7 @@ int dc_signal_param_set_val_without_check(const std::string &saddr, uint8_t data XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length()); stru_signal *p_signal = dc_find_signal(saddr, g_datacenter.signal_param); + printf("[SET_PARAM] saddr=%s zone=%d data=%.6f\n", saddr.c_str(), (int)setting_zone, *(float*)p_data); if(p_signal != nullptr && setting_zone < p_signal->vec_p_data.size()) { if(p_signal->data_type != data_type) @@ -1466,9 +1486,11 @@ int dc_signal_param_set_val_without_check(const std::string &saddr, uint8_t data } dc_set_signal_val(p_signal->vec_p_data[setting_zone], data_type, p_data); + printf("[SET_PARAM_OK] saddr=%s zone=%d -> vec[%d]=%.6f, %p\n", saddr.c_str(), (int)setting_zone, (int)setting_zone, *(float*)p_signal->vec_p_data[setting_zone], p_signal->vec_p_data[setting_zone]); dc_set_param_cfg_change(true); return 0; } + printf("[SET_PARAM_FAIL] saddr=%s zone=%d signal=%p size=%d\n", saddr.c_str(), (int)setting_zone, (void*)p_signal, p_signal ? (int)p_signal->vec_p_data.size() : -1); LOG_E("saddr %s not found in param table", saddr.c_str()); return -1; @@ -2161,12 +2183,16 @@ void dc_param_cfg_check(const std::string &path) sig_elem->SetAttribute("num", p_param->vec_p_data.size()); + printf("[SAVE_PARAM] saddr=%s num=%d\n", p_param->saddr.c_str(), (int)p_param->vec_p_data.size()); for(int i = 0; i < p_param->vec_p_data.size(); i++) { + std::string val = dc_get_signal_val(p_param->vec_p_data[i], p_param->data_type); + std::string def = dc_get_signal_val(p_param->vec_p_default_data[i], p_param->data_type); + printf(" zone %d: val=%s def=%s, %p, %p\n", i+1, val.c_str(), def.c_str(), p_param->vec_p_data[i], p_param->vec_p_default_data[i]); XMLElement *item_elem = doc.NewElement("Item"); item_elem->SetAttribute("index", i+1); - item_elem->SetAttribute("value", dc_get_signal_val(p_param->vec_p_data[i], p_param->data_type).c_str()); - item_elem->SetAttribute("default", dc_get_signal_val(p_param->vec_p_default_data[i], p_param->data_type).c_str()); + item_elem->SetAttribute("value", val.c_str()); + item_elem->SetAttribute("default", def.c_str()); sig_elem->InsertEndChild(item_elem); } diff --git a/src/system/libiec61850m/src/iec61850m.cpp b/src/system/libiec61850m/src/iec61850m.cpp index f7e466f..f1c6c85 100644 --- a/src/system/libiec61850m/src/iec61850m.cpp +++ b/src/system/libiec61850m/src/iec61850m.cpp @@ -99,7 +99,7 @@ LOCAL void mms_send_control(int fd, const char *saddr, const char *val, uint8_t MY_LOG_I("p_event->val %s", p_event->val); - mms_m_out_do_set_yk_or_param(p_event); + mms_m_out_do_set_yk(p_event); } LOCAL void mms_event_back(void *arg, int ret) @@ -123,7 +123,12 @@ LOCAL void mms_data_back(stru_mms_m_out_value *p) return; } - if(p->reason != IEC61850_REASON_DATA_CHANGE) + if(p->reason != IEC61850_REASON_DATA_CHANGE && + // p->reason != IEC61850_REASON_GI && + // p->reason != IEC61850_REASON_INTEGRITY && + // p->reason != 64 && // MMS_M_REASON_ALL_CALL + p->reason != MMS_M_REASON_READ_AO && // MMS_M_REASON_READ_PARAM + p->reason != MMS_M_REASON_READ_PARAM) { return; } @@ -141,6 +146,9 @@ LOCAL void mms_data_back(stru_mms_m_out_value *p) case MMS_FLOAT: printf("value %f, ", MY_GET_DATA_WITH_TYPE(p->p_value, float)); break; + case MMS_STRING: + printf("value %s, ", (char *)p->p_value); + break; default: break; } @@ -174,6 +182,33 @@ LOCAL void mms_data_back(stru_mms_m_out_value *p) dc_set_out_signal_val(p_cfg->point.p_mx[j].saddr, p->p_value); } } + + for(uint32_t j = 0; j < p_cfg->point.ao_num; j++) + { + if(strcmp(p_cfg->point.p_ao[j].saddr, p->name) == 0 && NULL != p_cfg->point.p_ao[j].value.p_val[0]) + { + auto it_ao = g_mms_m_type_to_local_type.find(p_cfg->point.p_ao[j].type); + uint8_t local_type = (it_ao != g_mms_m_type_to_local_type.end()) ? it_ao->second : 0; + if(local_type != 0) + { + dc_signal_ao_set_val_without_check(p_cfg->point.p_ao[j].saddr, local_type, p->p_value); + } + } + } + + for(uint32_t j = 0; j < p_cfg->point.param_num; j++) + { + if(strcmp(p_cfg->point.p_param[j].saddr, p->name) == 0 && NULL != p_cfg->point.p_param[j].value.p_val[0]) + { + auto it_param = g_mms_m_type_to_local_type.find(p_cfg->point.p_param[j].type); + uint8_t local_type = (it_param != g_mms_m_type_to_local_type.end()) ? it_param->second : 0; + if(local_type != 0) + { + printf("mms_data_back: set param %s zone=%d\n", p_cfg->point.p_param[j].saddr, p->set_zone); + dc_signal_param_set_val_without_check(p_cfg->point.p_param[j].saddr, local_type, p->set_zone - 1, p->p_value); + } + } + } } } } @@ -203,6 +238,8 @@ LOCAL void iec61850m_connect_status(int fd, int status) if (MMS_M_ON_LINE == status) { iec61850m_ext_demo(fd); + mms_m_out_read_ao_or_params(fd, _MMS_M_EVENT_AO_READ, NULL); + mms_m_out_read_ao_or_params(fd, _MMS_M_EVENT_PARAM_READ, NULL); } } @@ -565,6 +602,14 @@ int iec61850m_init() } MY_LOG_I("mms_m_out_init success, fd %d, no %d, prj_name %s", p_info->fd, i, p_info->prj_name); + + // Bind the first AO signal as the param zone indicator + stru_cfg *p_cfg = p_info->p_cfg; + if (p_cfg && p_cfg->point.ao_num > 0 && strlen(p_cfg->point.p_ao[0].saddr) > 0) + { + mms_m_out_bind_param_zone_signal(p_info->fd, p_cfg->point.p_ao[0].saddr); + } + mms_m_out_get_value(p_info->fd, mms_data_back); mms_m_out_get_connect_status(p_info->fd, iec61850m_connect_status); } diff --git a/src/system/libiec61850s/src/iec61850s.cpp b/src/system/libiec61850s/src/iec61850s.cpp index aa9c512..79a881d 100644 --- a/src/system/libiec61850s/src/iec61850s.cpp +++ b/src/system/libiec61850s/src/iec61850s.cpp @@ -326,13 +326,13 @@ LOCAL int iec61850s_param_signals_init(std::vector &vec_ return -1; } - param.param_num = p_data_vec.size(); - for(uint8_t i = 0; i < param.param_num; ++i) - { - param.p_data[i] = p_data_vec[i]; - } - g_vec_param.push_back(param); + + g_vec_param.back().param_num = p_data_vec.size(); + for(uint8_t i = 0; i < p_data_vec.size(); ++i) + { + g_vec_param.back().p_data[i] = p_data_vec[i]; + } } if(0 != mms_s_param_register(g_vec_param.data(), g_vec_param.size(), iec61850s_param_callback)) diff --git a/test/config/MMS/PCS.icd b/test/config/MMS/PCS.icd index 3eb8a23..fc4a377 100644 --- a/test/config/MMS/PCS.icd +++ b/test/config/MMS/PCS.icd @@ -5441,25 +5441,25 @@ - + - + @@ -5739,7 +5739,7 @@ - + - + diff --git a/test/config/MMS/mms_m.xml b/test/config/MMS/mms_m.xml index a6dacdc..fad4b17 100644 --- a/test/config/MMS/mms_m.xml +++ b/test/config/MMS/mms_m.xml @@ -29,7 +29,7 @@ - + \ No newline at end of file diff --git a/test/config/PARAM/param.xml b/test/config/PARAM/param.xml index 5320328..ab782ed 100644 --- a/test/config/PARAM/param.xml +++ b/test/config/PARAM/param.xml @@ -1499,7 +1499,7 @@ - + @@ -1509,16 +1509,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -1528,32 +1528,32 @@ - - - + + + - - - - - - + + + + + + - - - - - - - - - - + + + + + + + + + + - + @@ -1562,15 +1562,15 @@ - - + + - - - + + + - +