diff --git a/release/inc/myMms_m.h b/release/inc/myMms_m.h index f78417b..e77d670 100644 --- a/release/inc/myMms_m.h +++ b/release/inc/myMms_m.h @@ -167,6 +167,7 @@ int mms_m_out_do_set_yk(stru_mms_m_event *p_event); 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_set_rcb_numbers(int app_fd, const char *rcb_numbers); 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 2b898c0..1fb30e5 100644 --- a/src/protocol/libmms_m/inc/mms_m.h +++ b/src/protocol/libmms_m/inc/mms_m.h @@ -180,7 +180,8 @@ typedef struct MMS_STR zone_saddr; // 关联的定值区信号saddr(如ao.0) int current_zone; // 当前定值区号 - + std::vector rcb_numbers; // 要订阅的RCB编号列表,空=默认"01" + stru_mms_m_run run; // 运行时数据结构 std::vector ldevs; // 逻辑设备集合 diff --git a/src/protocol/libmms_m/src/mms_m.cpp b/src/protocol/libmms_m/src/mms_m.cpp index a2bdbab..8a28f32 100644 --- a/src/protocol/libmms_m/src/mms_m.cpp +++ b/src/protocol/libmms_m/src/mms_m.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -1338,6 +1339,24 @@ static int mms_m_icd_dataset_init(stru_mms_m_obj &obj, stru_ld_dataset &ld_ds) return 0; } +static bool mms_m_rcb_number_match(stru_mms_m_obj &obj, const std::string &rpt_no) +{ + if (obj.rcb_numbers.empty()) + { + return (rpt_no == "01"); + } + + for (auto &n : obj.rcb_numbers) + { + if (rpt_no == n) + { + return true; + } + } + + return false; +} + static int mms_m_icd_report_init(stru_mms_m_obj &obj, stru_ld_dataset &ld_ds, ACSIClass acsiClass) { if(ACSI_CLASS_URCB != acsiClass && ACSI_CLASS_BRCB != acsiClass) @@ -1376,7 +1395,7 @@ static int mms_m_icd_report_init(stru_mms_m_obj &obj, stru_ld_dataset &ld_ds, AC memset(&ln_rpt, 0, sizeof(ln_rpt)); ln_rpt.type = acsiClass; - if(0 == rpt_no.compare("01")) + if(mms_m_rcb_number_match(obj, rpt_no)) { ln_rpt.rpt_ref = rpt_ref + rpt_name; ln_rpt.rpt_ref_with_no = rpt_ref + rpt_name + rpt_no; @@ -2077,6 +2096,72 @@ int mms_m_out_bind_param_zone_signal(int app_fd, const char *zone_saddr) return 0; } +int mms_m_out_set_rcb_numbers(int app_fd, const char *rcb_numbers) +{ + 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; + } + + stru_mms_m_obj &obj = *g_mms_m_obj_map[app_fd]; + + obj.rcb_numbers.clear(); + + if(nullptr == rcb_numbers || strlen(rcb_numbers) == 0) + { + return 0; + } + + std::string input(rcb_numbers); + + if(input == "*") + { + obj.rcb_numbers.push_back("*"); + LOG_I("%s: rcb_numbers set to '*' (all)", obj.cfg_path.c_str()); + return 0; + } + + std::string token; + std::stringstream ss(input); + while(std::getline(ss, token, ',')) + { + while(!token.empty() && token[0] == ' ') + token.erase(0, 1); + while(!token.empty() && token[token.length() - 1] == ' ') + token.erase(token.length() - 1, 1); + + if(token.empty()) continue; + + if(token.length() != 2 || !isdigit(token[0]) || !isdigit(token[1])) + { + LOG_E("%s: invalid rcb number '%s'", obj.cfg_path.c_str(), token.c_str()); + obj.rcb_numbers.clear(); + return -1; + } + + obj.rcb_numbers.push_back(token); + } + + if(obj.rcb_numbers.empty()) + { + return 0; + } + + if(MMS_M_DEBUG_PRINT_ON == obj.debug_print_flag) + { + std::string dbg; + for(size_t i = 0; i < obj.rcb_numbers.size(); i++) + { + if(i > 0) dbg += ","; + dbg += obj.rcb_numbers[i]; + } + LOG_I("%s: rcb_numbers set to [%s]", obj.cfg_path.c_str(), dbg.c_str()); + } + + return 0; +} + 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()) diff --git a/src/system/libiec61850m/src/iec61850m.cpp b/src/system/libiec61850m/src/iec61850m.cpp index f1c6c85..57c9c36 100644 --- a/src/system/libiec61850m/src/iec61850m.cpp +++ b/src/system/libiec61850m/src/iec61850m.cpp @@ -603,6 +603,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); + if(0 != mms_m_out_set_rcb_numbers(p_info->fd, "01")) + // if(0 != mms_m_out_set_rcb_numbers(p_info->fd, "01,02,03")) + // if(0 != mms_m_out_set_rcb_numbers(p_info->fd, "*")) + { + MY_LOG_E("mms_m_out_set_rcb_numbers failed, fd %d, prj_name %s", p_info->fd, p_info->prj_name); + return -1; + } + // 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)