diff --git a/release/inc/myDatacenter.h b/release/inc/myDatacenter.h index 4b33056..e6688ad 100644 --- a/release/inc/myDatacenter.h +++ b/release/inc/myDatacenter.h @@ -146,7 +146,7 @@ typedef struct std::string saddr; uint8_t status; uint32_t sec; - uint16_t ums; + uint16_t ms; }stru_dc_soe; typedef struct diff --git a/release/inc/myMms_s.h b/release/inc/myMms_s.h index c519a50..3aab684 100644 --- a/release/inc/myMms_s.h +++ b/release/inc/myMms_s.h @@ -106,67 +106,49 @@ extern "C" { #define MMS_S_PARAM_MAX 16 +typedef void (*mms_s_value_update_cb)(const char * saddr, const char * val); + /** - * 参数/定值/控制的基础信息结构体 - * @field saddr 短地址(映射到 IEC61850 模型中的 sAddr 属性) - * @field desc 描述信息 - * @field type 数据类型(对应 DATA_TYPE_* 枚举) - * @field ctrl_model 控制模型类型 + * @brief 注册值更新回调函数 + * @param cb 值更新回调函数指针 */ +void mms_s_value_update_register(mms_s_value_update_cb *cb); + + typedef struct { char saddr[MMS_S_STR_LEN]; char desc[MMS_S_STR_LEN]; uint8_t type; uint8_t ctrl_model; -}stru_mms_s_param_base; +}stru_mms_s_signal_base; - -/** - * 定值数据结构体(一个定值点对应一个数据值) - * @field base 基础信息(saddr / desc / type) - * @field data 指向实际数据值的指针 - */ typedef struct { - stru_mms_s_param_base base; - void *data; + stru_mms_s_signal_base base; + void *p_data; }stru_mms_s_setting; -/** 定值回调函数类型:当定值被写入时调用 */ + typedef void (*mms_s_setting_cb)(stru_mms_s_setting *p_setting, const char *p_data); -/** - * 参数数据结构体(一个参数点可对应多个定值区的值) - * @field base 基础信息(saddr / desc / type) - * @field param_num 有效参数组数量 - * @field data 各组参数数据指针数组,最多 MMS_S_PARAM_MAX 个 - */ typedef struct { - stru_mms_s_param_base base; + stru_mms_s_signal_base base; uint8_t param_num; - void *data[MMS_S_PARAM_MAX]; + void *p_data[MMS_S_PARAM_MAX]; }stru_mms_s_param; -/** 参数回调函数类型:当参数区切换或被确认时调用 */ + typedef void (*mms_s_param_cb)(stru_mms_s_param *p_param, const char *p_data, int setting_zone); - -/** - * 控制对象数据结构体 - * @field saddr 短地址 - * @field desc 描述信息 - * @field ctrl_model 控制模型类型 - */ typedef struct { - char saddr[MMS_S_STR_LEN]; - char desc[MMS_S_STR_LEN]; - uint8_t ctrl_model; + stru_mms_s_signal_base base; + void *p_data; }stru_mms_s_control; -/** 控制操作回调函数类型:当控制命令被执行时调用 */ + typedef void (*mms_s_control_cb)(stru_mms_s_control *p_control, uint8_t state); diff --git a/src/protocol/libmms_s/src/mms_s_control.cpp b/src/protocol/libmms_s/src/mms_s_control.cpp index f25601a..aeade90 100644 --- a/src/protocol/libmms_s/src/mms_s_control.cpp +++ b/src/protocol/libmms_s/src/mms_s_control.cpp @@ -6,7 +6,7 @@ * Direct Operate 控制模型。 * * 【核心结构】 - * - vec_control : 外部注册的控制对象列表(由 mms_s_control_register() 设置) + * - g_vec_control : 外部注册的控制对象列表(由 mms_s_control_register() 设置) * - cb_control : 控制执行后的回调函数 * * 【两个关键回调】 @@ -29,7 +29,7 @@ #include "mms_s.h" /** 外部注册的控制对象列表 */ -LOCAL std::vector vec_control; +LOCAL std::vector g_vec_control; /** 控制操作回调函数 */ LOCAL mms_s_control_cb cb_control = NULL; @@ -116,9 +116,9 @@ LOCAL ControlHandlerResult control_handler(ControlAction action, void* parameter DataAttribute *stVal = it->p_all_do->map_all_da["stVal"]->DA; std::string saddr = it->p_all_do->map_all_da["stVal"]->DA->sAddr; - for(std::vector::iterator it_control = vec_control.begin(); it_control != vec_control.end(); ++it_control) + for(std::vector::iterator it_control = g_vec_control.begin(); it_control != g_vec_control.end(); ++it_control) { - if(it_control->saddr == saddr) + if(0 == saddr.compare(it_control->base.saddr)) { if(NULL != cb_control) { @@ -253,12 +253,12 @@ int mms_s_control_register(stru_mms_s_control *p_control, uint16_t num, mms_s_co return -1; } - vec_control.clear(); - vec_control.reserve(num); + g_vec_control.clear(); + g_vec_control.reserve(num); for(uint16_t i = 0; i < num; ++i) { - vec_control.push_back(p_control[i]); + g_vec_control.push_back(p_control[i]); } if(NULL != cb) @@ -285,9 +285,9 @@ int control_init(IedServer server, stru_icd &icd) return -1; } - if(vec_control.empty()) + if(g_vec_control.empty()) { - LOG_E("vec_control is empty"); + LOG_E("g_vec_control is empty"); return 0; } diff --git a/src/protocol/libmms_s/src/mms_s_param.cpp b/src/protocol/libmms_s/src/mms_s_param.cpp index 72ebbd5..dd5f7e8 100644 --- a/src/protocol/libmms_s/src/mms_s_param.cpp +++ b/src/protocol/libmms_s/src/mms_s_param.cpp @@ -5,7 +5,7 @@ * @details 定值组(Setting Group)允许多套定值间切换。本模块实现: * * 【数据结构】 - * - vec_params : 外部注册的参数列表,每个元素包含多组值(param_num 个) + * - g_vec_params : 外部注册的参数列表,每个元素包含多组值(param_num 个) * - g_param_cb : 参数回调函数 * * 【FC=SG vs FC=SE】 @@ -26,7 +26,7 @@ #include "myMms_s.h" #include "mms_s_param.h" -LOCAL std::vector vec_params; +LOCAL std::vector g_vec_params; LOCAL mms_s_param_cb g_param_cb = NULL; @@ -125,7 +125,7 @@ LOCAL int g_param_update_funcs_count = sizeof(g_param_update_funcs)/sizeof(g_par /** * 将指定定值组号的参数数据加载到 SG DA * - * 根据 vec_params 中每个参数的 data[actSG-1] 值,找到对应 sAddr+"_SG" 的 + * 根据 g_vec_params 中每个参数的 data[actSG-1] 值,找到对应 sAddr+"_SG" 的 * 模型节点,将值写入。 * * @param ld 逻辑设备 @@ -140,7 +140,7 @@ LOCAL void param_load_active_sg_values(stru_LDevice &ld, int actSG) return; } - for(std::vector::iterator it_param = vec_params.begin(); it_param != vec_params.end(); it_param++) + for(std::vector::iterator it_param = g_vec_params.begin(); it_param != g_vec_params.end(); it_param++) { std::string saddr = std::string(it_param->base.saddr) + "_SG"; @@ -149,7 +149,7 @@ LOCAL void param_load_active_sg_values(stru_LDevice &ld, int actSG) LOG_E("param_num %d is not enough for saddr %s, actSG %d", it_param->param_num, saddr.c_str(), actSG); continue; } - std::string val = mms_s_get_string_by_type(it_param->data[actSG-1], it_param->base.type); + std::string val = mms_s_get_string_by_type(it_param->p_data[actSG-1], it_param->base.type); if(p_icd->ied.map_saddr_point.find(saddr) == p_icd->ied.map_saddr_point.end()) { @@ -203,7 +203,7 @@ LOCAL void param_load_edit_sg_values(stru_LDevice &ld, int editSG) } - for(std::vector::iterator it_param = vec_params.begin(); it_param != vec_params.end(); it_param++) + for(std::vector::iterator it_param = g_vec_params.begin(); it_param != g_vec_params.end(); it_param++) { std::string saddr = std::string(it_param->base.saddr) + "_SE"; @@ -212,7 +212,7 @@ LOCAL void param_load_edit_sg_values(stru_LDevice &ld, int editSG) LOG_E("param_num %d is not enough for saddr %s, editSG %d", it_param->param_num, saddr.c_str(), editSG); continue; } - std::string val = mms_s_get_string_by_type(it_param->data[editSG-1], it_param->base.type); + std::string val = mms_s_get_string_by_type(it_param->p_data[editSG-1], it_param->base.type); if(p_icd->ied.map_saddr_point.find(saddr) == p_icd->ied.map_saddr_point.end()) { @@ -627,7 +627,7 @@ LOCAL void edit_sg_confirmation_handler(void* parameter, SettingGroupControlBloc } - for(std::vector::iterator it_param = vec_params.begin(); it_param != vec_params.end(); it_param++) + for(std::vector::iterator it_param = g_vec_params.begin(); it_param != g_vec_params.end(); it_param++) { std::string saddr_sg = std::string(it_param->base.saddr) + "_SG"; std::string saddr_se = std::string(it_param->base.saddr) + "_SE"; @@ -702,20 +702,20 @@ LOCAL MmsDataAccessError read_access_handler(LogicalDevice* ld, LogicalNode* ln, /** 调试用:打印所有参数信息 */ LOCAL void param_values_show() { - if(vec_params.empty()) + if(g_vec_params.empty()) { - LOG_E("vec_params is empty"); + LOG_E("g_vec_params is empty"); return; } - for(uint16_t i = 0; i < vec_params.size(); i++) + for(uint16_t i = 0; i < g_vec_params.size(); i++) { - stru_mms_s_param ¶m = vec_params[i]; + stru_mms_s_param ¶m = g_vec_params[i]; printf("saddr %s, desc %s, type %d\n", param.base.saddr, param.base.desc, param.base.type); for(uint8_t j = 0; j < param.param_num; j++) { - std::string val = mms_s_get_string_by_type(param.data[j], param.base.type); + std::string val = mms_s_get_string_by_type(param.p_data[j], param.base.type); printf("index %d, val %s\n", j, val.c_str()); } printf("\n"); @@ -737,12 +737,12 @@ int mms_s_param_register(stru_mms_s_param *p_param, uint16_t num, mms_s_param_cb return -1; } - vec_params.clear(); - vec_params.reserve(num); + g_vec_params.clear(); + g_vec_params.reserve(num); for(uint16_t i = 0; i < num; i++) { - vec_params.push_back(p_param[i]); + g_vec_params.push_back(p_param[i]); } if(NULL != cb) @@ -764,9 +764,9 @@ int mms_s_param_register(stru_mms_s_param *p_param, uint16_t num, mms_s_param_cb */ int param_init(IedServer server, stru_icd &icd) { - if(vec_params.empty()) + if(g_vec_params.empty()) { - LOG_E("vec_params is empty"); + LOG_E("g_vec_params is empty"); return 0; } diff --git a/src/protocol/libmms_s/src/mms_s_setting.cpp b/src/protocol/libmms_s/src/mms_s_setting.cpp index bce37f0..f016832 100644 --- a/src/protocol/libmms_s/src/mms_s_setting.cpp +++ b/src/protocol/libmms_s/src/mms_s_setting.cpp @@ -29,7 +29,7 @@ #include "mms_s_setting.h" -LOCAL std::vector vec_settings; +LOCAL std::vector g_vec_settings; LOCAL mms_s_setting_cb cb_setting = NULL; @@ -132,10 +132,10 @@ LOCAL int g_setting_update_funcs_count = sizeof(g_setting_update_funcs)/sizeof(g */ LOCAL void setting_value_init(IedServer server, stru_icd &icd) { - for(std::vector::iterator it = vec_settings.begin(); it != vec_settings.end(); it++) + for(std::vector::iterator it = g_vec_settings.begin(); it != g_vec_settings.end(); it++) { std::string sAddr = it->base.saddr; - std::string str = mms_s_get_string_by_type(it->data, it->base.type); + std::string str = mms_s_get_string_by_type(it->p_data, it->base.type); if(icd.ied.map_saddr_point.find(sAddr) == icd.ied.map_saddr_point.end()) { @@ -446,7 +446,7 @@ LOCAL MmsDataAccessError writeAccessHandler (DataAttribute* dataAttribute, MmsVa LOG_I("da name: %s, sAddr: %s, fc %d", dataAttribute->name, dataAttribute->sAddr, dataAttribute->fc); } - for(std::vector::iterator it = vec_settings.begin(); it != vec_settings.end(); it++) + for(std::vector::iterator it = g_vec_settings.begin(); it != g_vec_settings.end(); it++) { std::string sAddr = it->base.saddr; @@ -504,9 +504,9 @@ LOCAL MmsDataAccessError writeAccessHandler (DataAttribute* dataAttribute, MmsVa */ LOCAL void setting_handle_init(IedServer server, stru_icd &icd) { - for(int i = 0; i < vec_settings.size(); i++) + for(int i = 0; i < g_vec_settings.size(); i++) { - std::string sAddr = vec_settings[i].base.saddr; + std::string sAddr = g_vec_settings[i].base.saddr; if(icd.ied.map_saddr_point.find(sAddr) == icd.ied.map_saddr_point.end()) { @@ -543,9 +543,9 @@ LOCAL void setting_handle_init(IedServer server, stru_icd &icd) /** 调试用:打印已注册的定值信息 */ LOCAL void setting_values_show() { - for(int i = 0; i < vec_settings.size(); i++) + for(int i = 0; i < g_vec_settings.size(); i++) { - stru_mms_s_setting &setting = vec_settings[i]; + stru_mms_s_setting &setting = g_vec_settings[i]; LOG_I("saddr %s, desc %s, type %d", setting.base.saddr, setting.base.desc, setting.base.type); } @@ -566,12 +566,12 @@ int mms_s_setting_register(stru_mms_s_setting *p_setting, uint16_t num, mms_s_se return -1; } - vec_settings.clear(); - vec_settings.reserve(num); + g_vec_settings.clear(); + g_vec_settings.reserve(num); for(int i = 0; i < num; i++) { - vec_settings.push_back(p_setting[i]); + g_vec_settings.push_back(p_setting[i]); } if(cb != NULL) @@ -595,9 +595,9 @@ int mms_s_setting_register(stru_mms_s_setting *p_setting, uint16_t num, mms_s_se */ int setting_init(IedServer server, stru_icd &icd) { - if(vec_settings.empty()) + if(g_vec_settings.empty()) { - LOG_E("vec_settings is empty"); + LOG_E("g_vec_settings is empty"); return 0; } diff --git a/src/protocol/libmms_s/src/mms_s_value.cpp b/src/protocol/libmms_s/src/mms_s_value.cpp index 00dc24d..b1318ef 100644 --- a/src/protocol/libmms_s/src/mms_s_value.cpp +++ b/src/protocol/libmms_s/src/mms_s_value.cpp @@ -21,154 +21,152 @@ * - 找不到则默认为 0 */ +#include "myMms_s.h" #include "mms_s_value.h" // ==================== 值更新回调(当前 Unused,预留给 mms_s_values_update) ==================== -LOCAL void model_da_value_update_Boolean(IedServer server, DataAttribute *da, void *value); -LOCAL void model_da_value_update_INT32(IedServer server, DataAttribute *da, void *value); -LOCAL void model_da_value_update_INT32U(IedServer server, DataAttribute *da, void *value); -LOCAL void model_da_value_update_FLOAT32(IedServer server, DataAttribute *da, void *value); -LOCAL void model_da_value_update_Enum(IedServer server, DataAttribute *da, void *value); -LOCAL void model_da_value_update_Visible_String(IedServer server, DataAttribute *da, void *value); -LOCAL void model_da_value_update_Unicode_String(IedServer server, DataAttribute *da, void *value); -LOCAL void model_da_value_update_timesramp(IedServer server, DataAttribute *da, void *value); +LOCAL void model_da_value_update_Boolean(IedServer server, DataAttribute *da, std::string val); +LOCAL void model_da_value_update_INT32(IedServer server, DataAttribute *da, std::string val); +LOCAL void model_da_value_update_INT32U(IedServer server, DataAttribute *da, std::string val); +LOCAL void model_da_value_update_FLOAT32(IedServer server, DataAttribute *da, std::string val); +LOCAL void model_da_value_update_Enum(IedServer server, DataAttribute *da, std::string val); +LOCAL void model_da_value_update_Visible_String(IedServer server, DataAttribute *da, std::string val); +LOCAL void model_da_value_update_Unicode_String(IedServer server, DataAttribute *da, std::string val); +LOCAL void model_da_value_update_timesramp(IedServer server, DataAttribute *da, std::string val); -LOCAL struct + +typedef void (*value_update_cb)(IedServer server, DataAttribute *da, std::string val); +LOCAL std::map g_iec61850s_value_update_cb_map = { - const char *btype; - void (*value_update_cb)(IedServer server, DataAttribute *da, void *value); -}g_iec61850s_value_update_cb[] = -{ - {"BOOLEAN", model_da_value_update_Boolean}, - {"INT8", NULL}, - {"INT16", NULL}, - {"INT32", model_da_value_update_INT32}, - {"INT64", NULL}, - {"INT128", NULL}, - {"INT8U", NULL}, - {"INT16U", NULL}, - {"INT32U", model_da_value_update_INT32U}, - {"FLOAT32", model_da_value_update_FLOAT32}, - {"FLOAT64", NULL}, - {"Enum", model_da_value_update_Enum}, - {"Octet64", NULL}, - {"Octet6", NULL}, - {"Octet8", NULL}, - {"VisString32", model_da_value_update_Visible_String}, - {"VisString64", model_da_value_update_Visible_String}, - {"VisString65", model_da_value_update_Visible_String}, - {"VisString129", model_da_value_update_Visible_String}, - {"VisString255", model_da_value_update_Visible_String}, - {"Unicode255", model_da_value_update_Unicode_String}, - {"Timestamp", model_da_value_update_timesramp}, - {"Quality", NULL}, - {"Check", NULL}, - {"CodedEnum", NULL}, - {"BitString", NULL}, - {"Struct", NULL}, - {"EntryTime", NULL}, - {"PhyComAddr", NULL}, - {"Currency", NULL}, - {"OptFlds", NULL}, - {"TrgOps", NULL}, - {"Dbpos", NULL}, + {IEC61850_BOOLEAN, model_da_value_update_Boolean}, + {IEC61850_INT8, NULL}, + {IEC61850_INT16, NULL}, + {IEC61850_INT32, model_da_value_update_INT32}, + {IEC61850_INT64, NULL}, + {IEC61850_INT128, NULL}, + {IEC61850_INT8U, NULL}, + {IEC61850_INT16U, NULL}, + {IEC61850_INT32U, model_da_value_update_INT32U}, + {IEC61850_FLOAT32, model_da_value_update_FLOAT32}, + {IEC61850_FLOAT64, NULL}, + {IEC61850_ENUMERATED, model_da_value_update_Enum}, + {IEC61850_OCTET_STRING_64, NULL}, + {IEC61850_OCTET_STRING_6, NULL}, + {IEC61850_OCTET_STRING_8, NULL}, + {IEC61850_VISIBLE_STRING_32, model_da_value_update_Visible_String}, + {IEC61850_VISIBLE_STRING_64, NULL}, + {IEC61850_VISIBLE_STRING_65, NULL}, + {IEC61850_VISIBLE_STRING_129, NULL}, + {IEC61850_VISIBLE_STRING_255, NULL}, + {IEC61850_UNICODE_STRING_255, model_da_value_update_Unicode_String}, + {IEC61850_TIMESTAMP, model_da_value_update_timesramp}, + {IEC61850_QUALITY, NULL}, + {IEC61850_CHECK, NULL}, + {IEC61850_CODEDENUM, NULL}, + {IEC61850_GENERIC_BITSTRING, NULL}, + {IEC61850_CONSTRUCTED, NULL}, + {IEC61850_ENTRY_TIME, NULL}, + {IEC61850_PHYCOMADDR, NULL}, + {IEC61850_CURRENCY, NULL}, + {IEC61850_OPTFLDS, NULL}, + {IEC61850_TRGOPS, NULL}, + {IEC61850_DBPOS, NULL}, }; -LOCAL int g_iec61850s_value_update_cb_count = sizeof(g_iec61850s_value_update_cb) / sizeof(g_iec61850s_value_update_cb[0]); /** 更新 BOOLEAN 属性值(调用 IedServer_updateBooleanAttributeValue) */ -LOCAL void model_da_value_update_Boolean(IedServer server, DataAttribute *da, void *value) +LOCAL void model_da_value_update_Boolean(IedServer server, DataAttribute *da, std::string val) { - if(NULL == server || NULL == da || NULL == value || strlen((char*)value) == 0) + if(NULL == server || NULL == da || "" == val) { return; } - int int_value = atoi((char*)value); - if(int_value == 0) + + if(val == "false" || val == "0") { IedServer_updateBooleanAttributeValue(server, da, false); } - else if(int_value == 1) + else if(val == "true" || val == "1") { IedServer_updateBooleanAttributeValue(server, da, true); } else { - LOG_E("Invalid boolean value %s", (char *)value); + LOG_E("Invalid boolean value %s", val.c_str()); } } /** 更新 INT32 属性值 */ -LOCAL void model_da_value_update_INT32(IedServer server, DataAttribute *da, void *value) +LOCAL void model_da_value_update_INT32(IedServer server, DataAttribute *da, std::string val) { - if(NULL == server || NULL == da || NULL == value || strlen((char*)value) == 0) + if(NULL == server || NULL == da || "" == val) { return; } - IedServer_updateInt32AttributeValue(server, da, atoi((char*)value)); + IedServer_updateInt32AttributeValue(server, da, atoi(val.c_str())); } /** 更新 UINT32 属性值 */ -LOCAL void model_da_value_update_INT32U(IedServer server, DataAttribute *da, void *value) +LOCAL void model_da_value_update_INT32U(IedServer server, DataAttribute *da, std::string val) { - if(NULL == server || NULL == da || NULL == value || strlen((char*)value) == 0) + if(NULL == server || NULL == da || "" == val) { return; } - IedServer_updateUnsignedAttributeValue(server, da, atoi((char*)value)); + IedServer_updateUnsignedAttributeValue(server, da, atoi(val.c_str())); } /** 更新 FLOAT32 属性值 */ -LOCAL void model_da_value_update_FLOAT32(IedServer server, DataAttribute *da, void *value) +LOCAL void model_da_value_update_FLOAT32(IedServer server, DataAttribute *da, std::string val) { - if(NULL == server || NULL == da || NULL == value || strlen((char*)value) == 0) + if(NULL == server || NULL == da || "" == val) { return; } - IedServer_updateFloatAttributeValue(server, da, atof((char*)value)); + IedServer_updateFloatAttributeValue(server, da, atof(val.c_str())); } /** 更新 Enum 属性值(直接设置 mmsValue) */ -LOCAL void model_da_value_update_Enum(IedServer server, DataAttribute *da, void *value) +LOCAL void model_da_value_update_Enum(IedServer server, DataAttribute *da, std::string val) { - if(NULL == server || NULL == da || NULL == value) + if(NULL == server || NULL == da || "" == val) { return; } - LOG_I("da %p, name %s, value %d", da, da->name, *(int *)value); - da->mmsValue = MmsValue_newIntegerFromInt32(*(int *)value); + LOG_I("da %p, name %s, value %d", da, da->name, atoi(val.c_str())); + da->mmsValue = MmsValue_newIntegerFromInt32(atoi(val.c_str())); } /** 更新 VisibleString 属性值 */ -LOCAL void model_da_value_update_Visible_String(IedServer server, DataAttribute *da, void *value) +LOCAL void model_da_value_update_Visible_String(IedServer server, DataAttribute *da, std::string val) { - if(NULL == server || NULL == da || NULL == value || strlen((char*)value) == 0) + if(NULL == server || NULL == da || "" == val) { return; } - IedServer_updateVisibleStringAttributeValue(server, da, (char*)value); + IedServer_updateVisibleStringAttributeValue(server, da, (char*)val.c_str()); } /** 更新 Unicode String 属性值 */ -LOCAL void model_da_value_update_Unicode_String(IedServer server, DataAttribute *da, void *value) +LOCAL void model_da_value_update_Unicode_String(IedServer server, DataAttribute *da, std::string val) { - if(NULL == server || NULL == da || NULL == value || strlen((char*)value) == 0) + if(NULL == server || NULL == da || "" == val) { return; } - IedServer_updateAttributeValue(server, da, MmsValue_newMmsString((char*)value)); + IedServer_updateAttributeValue(server, da, MmsValue_newMmsString((char*)val.c_str())); } /** 更新 Timestamp 属性值(设为当前毫秒时间) */ -LOCAL void model_da_value_update_timesramp(IedServer server, DataAttribute *da, void *value) +LOCAL void model_da_value_update_timesramp(IedServer server, DataAttribute *da, std::string val) { if(NULL == server || NULL == da) { @@ -182,14 +180,14 @@ LOCAL void model_da_value_update_timesramp(IedServer server, DataAttribute *da, // ==================== 值初始化回调(mms_s_values_init 使用) ==================== -LOCAL void mms_s_da_value_init_BOOLEAN(DataAttribute *da, void *value); -LOCAL void mms_s_da_value_init_INT32(DataAttribute *da, void *value); -LOCAL void mms_s_da_value_init_INT32U(DataAttribute *da, void *value); -LOCAL void mms_s_da_value_init_FLOAT32(DataAttribute *da, void *value); -LOCAL void mms_s_da_value_init_Visible_String(DataAttribute *da, void *value); -LOCAL void mms_s_da_value_init_Unicode_String(DataAttribute *da, void *value); -LOCAL void mms_s_da_value_init_Timestamp(DataAttribute *da, void *value); -LOCAL void mms_s_da_value_init_Dbpos(DataAttribute *da, void *value); +LOCAL void mms_s_da_value_init_BOOLEAN(DataAttribute *da, std::string val); +LOCAL void mms_s_da_value_init_INT32(DataAttribute *da, std::string val); +LOCAL void mms_s_da_value_init_INT32U(DataAttribute *da, std::string val); +LOCAL void mms_s_da_value_init_FLOAT32(DataAttribute *da, std::string val); +LOCAL void mms_s_da_value_init_Visible_String(DataAttribute *da, std::string val); +LOCAL void mms_s_da_value_init_Unicode_String(DataAttribute *da, std::string val); +LOCAL void mms_s_da_value_init_Timestamp(DataAttribute *da, std::string val); +LOCAL void mms_s_da_value_init_Dbpos(DataAttribute *da, std::string val); /** * bType 到 DA 初始化函数的分发表 @@ -197,11 +195,10 @@ LOCAL void mms_s_da_value_init_Dbpos(DataAttribute *da, void *value); * 每个 bType 字符串对应一个初始化函数,用于将字符串值转换为 MmsValue 并设置到 DA。 * NULL 表示该类型暂不需要显式初始化(libiec61850 有默认行为)。 */ -LOCAL struct -{ - const char *bType; - void (*value_init)(DataAttribute *da, void *value); -}g_iec61850s_value_init_cb[] = + +typedef void (*value_init_cb)(DataAttribute *da, std::string val); + +LOCAL std::map g_iec61850s_value_init_cb_map = { {"BOOLEAN", mms_s_da_value_init_BOOLEAN}, {"INT8", NULL}, @@ -238,129 +235,127 @@ LOCAL struct {"Dbpos", mms_s_da_value_init_Dbpos}, }; -LOCAL int g_iec61850s_value_init_cb_count = sizeof(g_iec61850s_value_init_cb) / sizeof(g_iec61850s_value_init_cb[0]); - /** 初始化 BOOLEAN:根据 val 字符串 "true"/"1" 创建 MmsValue */ -LOCAL void mms_s_da_value_init_BOOLEAN(DataAttribute *da, void *value) +LOCAL void mms_s_da_value_init_BOOLEAN(DataAttribute *da, std::string val) { - if(NULL == da) + if(NULL == da || val.empty()) { - LOG_E("da is NULL"); + LOG_E("da or val is empty, da %p, val %s", da, val.c_str()); return; } - if(value == NULL || strlen((char*)value) == 0 || strcmp((char*)value, "false") == 0 || strcmp((char*)value, "0") == 0) + if(val == "false" || val == "0") { da->mmsValue = MmsValue_newBoolean(false); } - if(value != NULL && (strcmp((char*)value, "true") == 0 || strcmp((char*)value, "1") == 0)) + if(val == "true" || val == "1") { da->mmsValue = MmsValue_newBoolean(true); } } /** 初始化 INT32:根据 val 字符串创建 MmsValue */ -LOCAL void mms_s_da_value_init_INT32(DataAttribute *da, void *value) +LOCAL void mms_s_da_value_init_INT32(DataAttribute *da, std::string val) { - if(NULL == da) + if(NULL == da || val.empty()) { - LOG_E("da is NULL"); + LOG_E("da or val is empty, da %p, val %s", da, val.c_str()); return; } - if(value == NULL || strlen((char*)value) == 0) + if(val == "") { da->mmsValue = MmsValue_newIntegerFromInt32(0); } else { - da->mmsValue = MmsValue_newIntegerFromInt32(atoi((char*)value)); + da->mmsValue = MmsValue_newIntegerFromInt32(atoi(val.c_str())); } } /** 初始化 UINT32:根据 val 字符串创建 MmsValue */ -LOCAL void mms_s_da_value_init_INT32U(DataAttribute *da, void *value) +LOCAL void mms_s_da_value_init_INT32U(DataAttribute *da, std::string val) { - if(NULL == da) + if(NULL == da || val.empty()) { - LOG_E("da is NULL"); + LOG_E("da or val is empty, da %p, val %s", da, val.c_str()); return; } - if(value == NULL || strlen((char*)value) == 0) + if(val == "") { da->mmsValue = MmsValue_newUnsignedFromUint32(0); } else { - da->mmsValue = MmsValue_newUnsignedFromUint32(atoi((char*)value)); + da->mmsValue = MmsValue_newUnsignedFromUint32(atoi(val.c_str())); } } /** 初始化 FLOAT32:根据 val 字符串创建 MmsValue */ -LOCAL void mms_s_da_value_init_FLOAT32(DataAttribute *da, void *value) +LOCAL void mms_s_da_value_init_FLOAT32(DataAttribute *da, std::string val) { - if(NULL == da) + if(NULL == da || val.empty()) { - LOG_E("da is NULL"); + LOG_E("da or val is empty, da %p, val %s", da, val.c_str()); return; } - if(value == NULL || strlen((char*)value) == 0) + if(val == "") { da->mmsValue = MmsValue_newFloat(0.0); } else { - da->mmsValue = MmsValue_newFloat(atof((char*)value)); + da->mmsValue = MmsValue_newFloat(atof(val.c_str())); } } /** 初始化 VisibleString:根据 val 字符串创建 MmsValue */ -LOCAL void mms_s_da_value_init_Visible_String(DataAttribute *da, void *value) +LOCAL void mms_s_da_value_init_Visible_String(DataAttribute *da, std::string val) { - if(NULL == da) + if(NULL == da || val.empty()) { - LOG_E("da is NULL"); + LOG_E("da or val is empty, da %p, val %s", da, val.c_str()); return; } - if(value == NULL || strlen((char*)value) == 0) + if(val == "") { da->mmsValue = MmsValue_newVisibleString(""); } else { - da->mmsValue = MmsValue_newVisibleString((char*)value); + da->mmsValue = MmsValue_newVisibleString(val.c_str()); } } /** 初始化 Unicode String:根据 val 字符串创建 MmsValue */ -LOCAL void mms_s_da_value_init_Unicode_String(DataAttribute *da, void *value) +LOCAL void mms_s_da_value_init_Unicode_String(DataAttribute *da, std::string val) { - if(NULL == da) + if(NULL == da || val.empty()) { - LOG_E("da is NULL"); + LOG_E("da or val is empty, da %p, val %s", da, val.c_str()); return; } - if(value == NULL || strlen((char*)value) == 0) + if(val == "") { da->mmsValue = MmsValue_newMmsString(""); } else { - da->mmsValue = MmsValue_newMmsString((char*)value); + da->mmsValue = MmsValue_newMmsString(val.c_str()); } } /** 初始化 Timestamp:设为当前毫秒时间 */ -LOCAL void mms_s_da_value_init_Timestamp(DataAttribute *da, void *value) +LOCAL void mms_s_da_value_init_Timestamp(DataAttribute *da, std::string val) { - if(NULL == da) + if(NULL == da || val.empty()) { - LOG_E("da is NULL"); + LOG_E("da or val is empty, da %p, val %s", da, val.c_str()); return; } @@ -371,23 +366,23 @@ LOCAL void mms_s_da_value_init_Timestamp(DataAttribute *da, void *value) * 初始化 Dbpos(双点位置): * val=0 → INTERMEDIATE_STATE, 1 → OFF, 2 → ON, 3/其他 → BAD_STATE */ -LOCAL void mms_s_da_value_init_Dbpos(DataAttribute *da, void *value) +LOCAL void mms_s_da_value_init_Dbpos(DataAttribute *da, std::string val) { - if(NULL == da) + if(NULL == da || val.empty()) { - LOG_E("da is NULL"); + LOG_E("da or val is empty, da %p, val %s", da, val.c_str()); return; } Dbpos pos = DBPOS_INTERMEDIATE_STATE; - if(value == NULL || strlen((char*)value) == 0) + if(val == "") { pos = DBPOS_INTERMEDIATE_STATE; } else { - int i = atoi((char*)value); + int i = atoi(val.c_str()); if(i == 0) { pos = DBPOS_INTERMEDIATE_STATE; @@ -414,7 +409,7 @@ LOCAL void mms_s_da_value_init_Dbpos(DataAttribute *da, void *value) if(mms_s_dbg_get()) { - LOG_I("da %s-%s, value %s, pos %d", da->parent->name, da->name, (char *)value, pos); + LOG_I("da %s-%s, value %s, pos %d", da->parent->name, da->name, val.c_str(), pos); } } @@ -476,22 +471,16 @@ LOCAL void mms_s_da_values_init(stru_icd &icd, std::string da_name, stru_all_DA } else { - for(int i = 0; i < g_iec61850s_value_init_cb_count; i++) + if(g_iec61850s_value_init_cb_map.find(p_all_da->bType) == g_iec61850s_value_init_cb_map.end()) { - if(p_all_da->bType.compare(g_iec61850s_value_init_cb[i].bType) == 0) - { - if(NULL != g_iec61850s_value_init_cb[i].value_init) - { - g_iec61850s_value_init_cb[i].value_init(p_all_da->DA, (void *)p_all_da->val.c_str()); - } - else - { - } - return; - } + LOG_E("BDAType %s not found in ICD", p_all_da->bType.c_str()); + return; } - LOG_E("BDAType %s not found in ICD", p_all_da->bType.c_str()); + if(NULL != g_iec61850s_value_init_cb_map[p_all_da->bType]) + { + g_iec61850s_value_init_cb_map[p_all_da->bType](p_all_da->DA, p_all_da->val); + } } } @@ -546,4 +535,66 @@ void mms_s_values_init() mms_s_do_values_init(*p_icd, it_ln->map_all_do); } } +} + +LOCAL void mms_s_value_update(const char *str_saddr, const char *str_val) +{ + if(NULL == str_saddr || NULL == str_val) + { + LOG_E("str_saddr or str_val is NULL, str_saddr %p, str_val %p", str_saddr, str_val); + return; + } + + std::string saddr = str_saddr; + std::string val = str_val; + + stru_icd *p_icd = mms_s_get_icd_ptr(); + if(NULL == p_icd) + { + LOG_E("p_icd is NULL"); + return; + } + + std::map map_saddr_point = p_icd->ied.map_saddr_point; + + if(map_saddr_point.find(saddr) == map_saddr_point.end()) + { + LOG_E("sAddr %s not found in ICD", saddr.c_str()); + return; + } + + stru_saddr_point &saddr_point = map_saddr_point[saddr]; + + ModelNode *p_node = saddr_point.node; + if(NULL == p_node) + { + LOG_E("p_node is NULL"); + return; + } + + if(p_node->modelType != DataAttributeModelType) + { + LOG_E("p_node is not a DataAttribute"); + return; + } + + DataAttribute *p_da = (DataAttribute *)p_node; + + if(g_iec61850s_value_update_cb_map.find(p_da->type) == g_iec61850s_value_update_cb_map.end()) + { + LOG_E("EnumType %d not found in ICD", p_da->type); + return; + } + + IedServer p_ied_server = mms_s_get_ied_server_ptr(); + + if(NULL != g_iec61850s_value_update_cb_map[p_da->type] && p_ied_server != NULL) + { + g_iec61850s_value_update_cb_map[p_da->type](p_ied_server, p_da, val); + } +} + +void mms_s_value_update_register(mms_s_value_update_cb *cb) +{ + (*cb) = mms_s_value_update; } \ No newline at end of file diff --git a/src/system/libdatacenter/src/dc_event.cpp b/src/system/libdatacenter/src/dc_event.cpp index d694e00..0f48d0b 100644 --- a/src/system/libdatacenter/src/dc_event.cpp +++ b/src/system/libdatacenter/src/dc_event.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "dc_event.h" #include "myLog.h" @@ -20,6 +21,15 @@ LOCAL std::queue g_fault_queue; LOCAL std::vector g_fault_queue_pop_cbs; +LOCAL void dc_get_unix_time(uint32_t &sec, uint16_t &ms) +{ + struct timeval tv; + gettimeofday(&tv, nullptr); + sec = tv.tv_sec; + ms = tv.tv_usec / 1000; +} + + int dc_disturb_dd_register_queue_pop(dc_queue_pop_cb cb) { if(!cb) @@ -35,8 +45,15 @@ int dc_disturb_dd_register_queue_pop(dc_queue_pop_cb cb) int dc_disturb_dd_queue_push(const stru_disturb_dd &dd) { + stru_disturb_dd local_dd = dd; + if(dd.sec == 0 && dd.ms == 0) + { + dc_get_unix_time(local_dd.sec, local_dd.ms); + } + std::lock_guard lock(g_disturb_dd_mutex); - g_disturb_dd_queue.push(dd); + + g_disturb_dd_queue.push(local_dd); return 0; } @@ -77,8 +94,14 @@ int dc_event_register_queue_pop(dc_queue_pop_cb cb) int dc_event_queue_push(const stru_dc_soe &soe) { + stru_dc_soe local_soe = soe; + if(soe.sec == 0 && soe.ms == 0) + { + dc_get_unix_time(local_soe.sec, local_soe.ms); + } + std::lock_guard lock(g_soe_mutex); - g_soe_queue.push(soe); + g_soe_queue.push(local_soe); return 0; } @@ -119,8 +142,21 @@ int dc_fault_register_queue_pop(dc_queue_pop_cb cb) int dc_fault_queue_push(const stru_dc_fault &fault) { + stru_dc_fault local_fault = fault; + if(local_fault.vec_soe.empty()) + { + LOG_E("dc_fault_queue_push: vec_soe is empty"); + return -1; + } + + stru_dc_soe &soe = local_fault.vec_soe[0]; + if(soe.sec == 0 && soe.ms == 0) + { + dc_get_unix_time(soe.sec, soe.ms); + } + std::lock_guard lock(g_fault_mutex); - g_fault_queue.push(fault); + g_fault_queue.push(local_fault); return 0; } diff --git a/src/system/libiec/src/iec_point.cpp b/src/system/libiec/src/iec_point.cpp index f164d11..8e74208 100644 --- a/src/system/libiec/src/iec_point.cpp +++ b/src/system/libiec/src/iec_point.cpp @@ -132,8 +132,8 @@ LOCAL void iec_event_queue_callback(void *p_data) if(iec_cfg_ptr_get()->vec_st[i].link.compare(soe.saddr) == 0) { LOG_I("iec_event_queue_callback: found saddr %s in vec_st, set status %d, sec %d, ums %d", - soe.saddr.c_str(), soe.status, soe.sec, soe.ums); - UserWriteSoeEvent(i, soe.status, soe.sec, soe.ums); + soe.saddr.c_str(), soe.status, soe.sec, soe.ms); + UserWriteSoeEvent(i, soe.status, soe.sec, soe.ms); } } @@ -167,7 +167,7 @@ LOCAL void iec_fault_queue_callback(void *p_data) soe_info.uiInfoAddr = i; soe_info.ucStatus = fault.vec_soe[0].status; soe_info.uiSeconds = fault.vec_soe[0].sec; - soe_info.usMs = fault.vec_soe[0].ums; + soe_info.usMs = fault.vec_soe[0].ms; break; } } diff --git a/src/system/libiec61850m/src/iec61850m.cpp b/src/system/libiec61850m/src/iec61850m.cpp index 5c1d5f0..caf4560 100644 --- a/src/system/libiec61850m/src/iec61850m.cpp +++ b/src/system/libiec61850m/src/iec61850m.cpp @@ -7,7 +7,7 @@ LOCAL void mms_event_back(void *arg, int ret); -LOCAL const char *g_61850m_prj_path = "/mnt/RTU/test/file/MMS/"; +LOCAL const char *g_61850m_prj_path = "/mnt/RTU/test/config/MMS/"; typedef struct { diff --git a/src/system/libiec61850s/inc/parse_xml.h b/src/system/libiec61850s/inc/parse_xml.h new file mode 100644 index 0000000..5b15a51 --- /dev/null +++ b/src/system/libiec61850s/inc/parse_xml.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include + + +#include "myBase.h" +#include "myMms_s.h" +#include "tinyxml2.h" + + + +typedef struct +{ + std::vector vec_st; + std::vector vec_mx; + std::vector vec_co; + std::vector vec_ao; + std::vector vec_param; +}stru_mms_cfg; + + + +int parse_mms_xml(const std::string &path); +void show_mms_xml(stru_mms_cfg &cfg); + +stru_mms_cfg *mms_cfg_ptr_get(void); \ No newline at end of file diff --git a/src/system/libiec61850s/src/iec61850s.cpp b/src/system/libiec61850s/src/iec61850s.cpp index cd20aae..bd86adc 100644 --- a/src/system/libiec61850s/src/iec61850s.cpp +++ b/src/system/libiec61850s/src/iec61850s.cpp @@ -3,36 +3,96 @@ #include "myLog.h" #include "myCmd.h" #include "myDatacenter.h" +#include "parse_xml.h" -LOCAL std::vector vec_control = +typedef struct { - {"iec61850m.prj.co.0", "遥控01", 4}, - {"iec61850m.prj.co.1", "遥控02", 4}, - {"iec61850m.prj.co.2", "遥控03", 4}, - {"iec61850m.prj.co.3", "遥控04", 4}, -}; + stru_mms_s_signal_base base; + void *p_data; +}stru_local_st_mx; -LOCAL std::vector vec_setting = +LOCAL std::vector g_vec_st = {}; +LOCAL std::vector g_vec_mx = {}; +LOCAL std::vector g_vec_control = {}; +LOCAL std::vector g_vec_setting = {}; +LOCAL std::vector g_vec_param = {}; +LOCAL mms_s_value_update_cb g_mms_s_value_update_cb = NULL; + + +LOCAL void iec61850s_st_mx_change_callback(std::string saddr, uint8_t data_type, void *p_data, void *p_last_data) { + if(NULL == p_data || NULL == p_last_data) { - .base = {.saddr = "iec61850m.prj.ao.0", .desc = "参数01", .type = DATA_TYPE_S32}, - .data = NULL, - }, - { - .base = {.saddr = "iec61850m.prj.ao.1", .desc = "参数02", .type = DATA_TYPE_STR}, - .data = NULL, + LOG_E("p_data or p_last_data is NULL"); + return; } -}; -LOCAL std::vector vec_param = -{ + std::string val = dc_get_signal_val(p_data, data_type); + if(val.empty()) { - .base = {.saddr = "iec61850m.prj.param.0", .desc = "定值01", .type = DATA_TYPE_F32}, - .data = NULL, - }, -}; + LOG_E("val is empty"); + return; + } -void iec61850s_control_callback(stru_mms_s_control *p_control, uint8_t state) + LOG_I("st mx change callback saddr: %s, val: %s", saddr.c_str(), val.c_str()); + if(g_mms_s_value_update_cb != NULL) + { + g_mms_s_value_update_cb(saddr.c_str(), val.c_str()); + } +} + +LOCAL int iec61850s_st_signals_init(std::vector &vec_st) +{ + LOG_I("st signals init, vec_st size: %i", vec_st.size()); + + g_vec_st.clear(); + g_vec_st.reserve(vec_st.capacity()); + + for(auto &it : vec_st) + { + stru_local_st_mx st = {}; + st.base = it; + std::string desc = ""; + + if(0 != dc_signal_out_link_with_callback(st.base.saddr, &st.p_data, iec61850s_st_mx_change_callback)) + { + LOG_E("dc_signal_out_link_with_callback failed"); + return -1; + } + + g_vec_st.push_back(st); + } + + return 0; +} + +LOCAL int iec61850s_mx_signals_init(std::vector &vec_mx) +{ + LOG_I("mx signals init, vec_mx size: %i", vec_mx.size()); + + g_vec_mx.clear(); + g_vec_mx.reserve(vec_mx.capacity()); + + for(auto &it : vec_mx) + { + stru_local_st_mx mx = {}; + mx.base = it; + std::string desc = ""; + + if(0 != dc_signal_out_link_with_callback(mx.base.saddr, &mx.p_data, iec61850s_st_mx_change_callback)) + { + LOG_E("dc_signal_out_link_with_callback failed"); + return -1; + } + + g_vec_mx.push_back(mx); + } + + return 0; +} + + +LOCAL void iec61850s_control_callback(stru_mms_s_control *p_control, uint8_t state) { if(NULL == p_control) { @@ -40,7 +100,9 @@ void iec61850s_control_callback(stru_mms_s_control *p_control, uint8_t state) return; } - LOG_I("control callback called saddr: %s, state: %i", p_control->saddr, state); + stru_mms_s_signal_base &base = p_control->base; + + LOG_I("control callback called saddr: %s, state: %i", base.saddr, state); uint8_t temp_st = 0; stru_signal_ctrl ctrl = { @@ -50,38 +112,67 @@ void iec61850s_control_callback(stru_mms_s_control *p_control, uint8_t state) .p_data = &temp_st, }; - if(p_control->ctrl_model == CONTROL_MODEL_DIRECT_NORMAL || p_control->ctrl_model == CONTROL_MODEL_DIRECT_ENHANCED) + if(base.ctrl_model == CONTROL_MODEL_DIRECT_NORMAL || base.ctrl_model == CONTROL_MODEL_DIRECT_ENHANCED) { ctrl.type = SIGNAL_CTRL_TYPE::DIRECT_NORMAL; - if(0 != dc_signal_yk_set_status(p_control->saddr, SIGNAL_CTRL_STEP::DIRECT, ctrl, &state)) + if(0 != dc_signal_yk_set_status(base.saddr, SIGNAL_CTRL_STEP::DIRECT, ctrl, &state)) { MY_LOG_E("dc_signal_yk_set_status failed"); return; } } - else if(p_control->ctrl_model == CONTROL_MODEL_SBO_NORMAL || p_control->ctrl_model == CONTROL_MODEL_SBO_ENHANCED) + else if(base.ctrl_model == CONTROL_MODEL_SBO_NORMAL || base.ctrl_model == CONTROL_MODEL_SBO_ENHANCED) { ctrl.type = SIGNAL_CTRL_TYPE::SBO_NORMAL; - if(0 != dc_signal_yk_set_status(p_control->saddr, SIGNAL_CTRL_STEP::SELECT, ctrl, &state)) + if(0 != dc_signal_yk_set_status(base.saddr, SIGNAL_CTRL_STEP::SELECT, ctrl, &state)) { MY_LOG_E("dc_signal_yk_set_status failed"); return; } - if(0 != dc_signal_yk_set_status(p_control->saddr, SIGNAL_CTRL_STEP::DIRECT, ctrl, &state)) + if(0 != dc_signal_yk_set_status(base.saddr, SIGNAL_CTRL_STEP::DIRECT, ctrl, &state)) { MY_LOG_E("dc_signal_yk_set_status failed"); return; } } - else if(p_control->ctrl_model == CONTROL_MODEL_STATUS_ONLY) + else if(base.ctrl_model == CONTROL_MODEL_STATUS_ONLY) { MY_LOG_I("CONTROL_MODEL_STATUS_ONLY"); return; } } -void iec61850s_setting_callback(stru_mms_s_setting *p_setting, const char *p_data) +LOCAL int iec61850s_control_signals_init(std::vector &vec_co) +{ + g_vec_control.clear(); + g_vec_control.reserve(vec_co.size()); + + for(std::vector::iterator it = vec_co.begin(); it != vec_co.end(); ++it) + { + stru_mms_s_control control = {}; + control.base = *it; + + std::string desc = ""; + + if(0 != dc_get_yk_signal_info(control.base.saddr, desc, control.base.type, control.base.ctrl_model, &control.p_data)) + { + MY_LOG_E("dc_get_yk_signal_info failed, saddr: %s, desc: %s", control.base.saddr, desc.c_str()); + return -1; + } + + g_vec_control.push_back(control); + } + + if(0 != mms_s_control_register(g_vec_control.data(), g_vec_control.size(), iec61850s_control_callback)) + { + MY_LOG_E("mms_s_control_register failed"); + return -1; + } + return 0; +} + +LOCAL void iec61850s_setting_callback(stru_mms_s_setting *p_setting, const char *p_data) { if(NULL == p_setting || NULL == p_data) { @@ -128,7 +219,36 @@ void iec61850s_setting_callback(stru_mms_s_setting *p_setting, const char *p_dat } } -void iec61850s_param_callback(stru_mms_s_param *p_param, const char *p_data, int setting_zone) +LOCAL int iec61850s_setting_signals_init(std::vector &vec_ao) +{ + g_vec_setting.clear(); + g_vec_setting.reserve(vec_ao.size()); + + for(std::vector::iterator it = vec_ao.begin(); it != vec_ao.end(); ++it) + { + stru_mms_s_setting setting = {}; + setting.base = *it; + + std::string desc = ""; + + if(0 != dc_get_ao_signal_info(setting.base.saddr, desc, setting.base.type, nullptr, setting.base.ctrl_model, &setting.p_data, nullptr)) + { + MY_LOG_E("dc_get_ao_signal_info failed, saddr: %s, desc: %s", setting.base.saddr, desc.c_str()); + return -1; + } + + g_vec_setting.push_back(setting); + } + + if(0 != mms_s_setting_register(g_vec_setting.data(), g_vec_setting.size(), iec61850s_setting_callback)) + { + MY_LOG_E("mms_s_setting_register failed"); + return -1; + } + return 0; +} + +LOCAL void iec61850s_param_callback(stru_mms_s_param *p_param, const char *p_data, int setting_zone) { if(NULL == p_param || NULL == p_data) { @@ -175,63 +295,118 @@ void iec61850s_param_callback(stru_mms_s_param *p_param, const char *p_data, int } } +LOCAL int iec61850s_param_signals_init(std::vector &vec_param) +{ + g_vec_param.clear(); + g_vec_param.reserve(vec_param.size()); + + for(std::vector::iterator it = vec_param.begin(); it != vec_param.end(); ++it) + { + stru_mms_s_param param = {}; + param.base = *it; + + std::string desc = ""; + std::vector p_data_vec; + + if(0 != dc_get_param_signal_info(param.base.saddr, desc, param.base.type, nullptr, param.base.ctrl_model, &p_data_vec, nullptr)) + { + MY_LOG_E("dc_get_param_signal_info failed, saddr: %s, desc: %s", param.base.saddr, desc.c_str()); + 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); + } + + if(0 != mms_s_param_register(g_vec_param.data(), g_vec_param.size(), iec61850s_param_callback)) + { + MY_LOG_E("mms_s_param_register failed"); + return -1; + } + return 0; +} + + +int iec61850s_signals_init() +{ + stru_mms_cfg *p_cfg = mms_cfg_ptr_get(); + if(NULL == p_cfg) + { + MY_LOG_E("mms_cfg_ptr_get failed"); + return -1; + } + + show_mms_xml(*p_cfg); + + if(0 != iec61850s_st_signals_init(p_cfg->vec_st)) + { + MY_LOG_E("iec61850s_st_signals_init failed"); + return -1; + } + + if(0 != iec61850s_mx_signals_init(p_cfg->vec_mx)) + { + MY_LOG_E("iec61850s_mx_signals_init failed"); + return -1; + } + + if(0 != iec61850s_control_signals_init(p_cfg->vec_co)) + { + MY_LOG_E("iec61850s_control_signals_init failed"); + return -1; + } + + if(0 != iec61850s_setting_signals_init(p_cfg->vec_ao)) + { + MY_LOG_E("iec61850s_setting_signals_init failed"); + return -1; + } + + if(0 != iec61850s_param_signals_init(p_cfg->vec_param)) + { + MY_LOG_E("iec61850s_param_signals_init failed"); + return -1; + } + + return 0; +} + + int app_iec61850s_init1(void *arg) { + if(0 != parse_mms_xml("/mnt/RTU/test/config/MMS/mms_s.xml")) + { + MY_LOG_E("parse_mms_xml failed"); + return -1; + } + + mms_s_dbg_switch(true); mms_s_file_path_set("/mnt/RTU/test/"); - mms_s_control_register(vec_control.data(), vec_control.size(), iec61850s_control_callback); - + mms_s_value_update_register(&g_mms_s_value_update_cb); + if(NULL == g_mms_s_value_update_cb) + { + MY_LOG_E("g_mms_s_value_update_cb is NULL"); + return -1; + } return 0; } int app_iec61850s_init2(void *arg) { - for(std::vector::iterator it = vec_setting.begin(); it != vec_setting.end(); ++it) + if(0 != iec61850s_signals_init()) { - std::string desc = ""; - uint8_t data_type = 0; - uint8_t ctrl_type = 0; - - if(0 != dc_get_ao_signal_info(it->base.saddr, desc, data_type, nullptr, ctrl_type, (void **)&it->data, nullptr)) - { - MY_LOG_E("dc_get_ao_signal_info failed"); - return -1; - } - - strcpy(it->base.desc, desc.c_str()); - it->base.type = data_type; - it->base.ctrl_model = ctrl_type; - } - - for(std::vector::iterator it = vec_param.begin(); it != vec_param.end(); ++it) - { - std::string desc = ""; - uint8_t data_type = 0; - uint8_t ctrl_type = 0; - std::vector vec_p_data = {}; - - if(0 != dc_get_param_signal_info(it->base.saddr, desc, data_type, nullptr, ctrl_type, &vec_p_data, nullptr)) - { - MY_LOG_E("dc_get_param_signal_info failed"); - return -1; - } - - strcpy(it->base.desc, desc.c_str()); - it->base.type = data_type; - it->base.ctrl_model = ctrl_type; - - it->param_num = vec_p_data.size(); - for(uint8_t j = 0; j < it->param_num; j++) - { - it->data[j] = (uint8_t *)vec_p_data[j]; - } + MY_LOG_E("iec61850s_signals_init failed"); + return -1; } - mms_s_setting_register(vec_setting.data(), vec_setting.size(), iec61850s_setting_callback); - mms_s_param_register(vec_param.data(), vec_param.size(), iec61850s_param_callback); - - if(0 != mms_s_init("/mnt/RTU/test/file/MMS/PCS.icd", 102)) + if(0 != mms_s_init("/mnt/RTU/test/config/MMS/PCS.icd", 102)) { MY_LOG_E("mms_s_init failed"); return -1; diff --git a/src/system/libiec61850s/src/parse_xml.cpp b/src/system/libiec61850s/src/parse_xml.cpp new file mode 100644 index 0000000..d07d2d7 --- /dev/null +++ b/src/system/libiec61850s/src/parse_xml.cpp @@ -0,0 +1,129 @@ +#include "parse_xml.h" + + +using namespace tinyxml2; + + + +LOCAL const char *ele_St = "St"; +LOCAL const char *ele_Mx = "Mx"; +LOCAL const char *ele_Co = "Co"; +LOCAL const char *ele_Ao = "Ao"; +LOCAL const char *ele_Param = "Param"; + +LOCAL const char *ele_Signal = "Signal"; + +LOCAL const char *attr_No = "no"; +LOCAL const char *attr_Link = "link"; +LOCAL const char *attr_Desc = "desc"; + + + + + +LOCAL stru_mms_cfg g_cfg = {}; + +std::map *> g_vec_map_signal = +{ + {ele_St, &g_cfg.vec_st}, + {ele_Mx, &g_cfg.vec_mx}, + {ele_Co, &g_cfg.vec_co}, + {ele_Ao, &g_cfg.vec_ao}, + {ele_Param, &g_cfg.vec_param}, +}; + + +LOCAL int parse_base(XMLElement *root) +{ + if(root == nullptr) + { + MY_LOG_E("root is nullptr"); + return -1; + } + + for(std::map *>::iterator it = g_vec_map_signal.begin(); it != g_vec_map_signal.end(); ++it) + { + XMLElement *ele = root->FirstChildElement(it->first.c_str()); + if(ele == nullptr) + { + MY_LOG_E("FirstChildElement failed, ele: %s", it->first.c_str()); + return -1; + } + + XMLElement *signal_ele = ele->FirstChildElement(ele_Signal); + while(signal_ele != nullptr) + { + stru_mms_s_signal_base base = {0}; + std::string saddr = signal_ele->Attribute(attr_Link) ? signal_ele->Attribute(attr_Link) : ""; + // std::string desc = signal_ele->Attribute(attr_Desc) ? signal_ele->Attribute(attr_Desc) : ""; + + if(saddr.empty() || saddr.length() > MMS_S_STR_LEN - 1) + { + MY_LOG_E("saddr is empty or length is too long, saddr: %s, len: %d", saddr.c_str(), saddr.length()); + return -1; + } + + strcpy(base.saddr, saddr.c_str()); + base.type = 0; + base.ctrl_model = 0; + it->second->push_back(base); + signal_ele = signal_ele->NextSiblingElement(ele_Signal); + } + } + + return 0; +} + + +int parse_mms_xml(const std::string &path) +{ + XMLDocument doc; + if(XML_SUCCESS != doc.LoadFile(path.c_str())) + { + MY_LOG_E("LoadFile failed, path: %s", path.c_str()); + return -1; + } + + XMLElement *root = doc.RootElement(); + if(root == nullptr) + { + MY_LOG_E("RootElement is nullptr"); + return -1; + } + + if(0 != parse_base(root)) + { + MY_LOG_E("parse_base failed"); + return -1; + } + + + return 0; +} + +void show_mms_xml(stru_mms_cfg &cfg) +{ + std::map *> vec_map = + { + {ele_St, &cfg.vec_st}, + {ele_Mx, &cfg.vec_mx}, + {ele_Co, &cfg.vec_co}, + {ele_Ao, &cfg.vec_ao}, + {ele_Param, &cfg.vec_param}, + }; + + for(auto &it : vec_map) + { + MY_LOG_I("ele: %s, size: %d", it.first.c_str(), it.second->size()); + + for(int i = 0; i < it.second->size(); ++i) + { + MY_LOG_I("saddr: %s, desc: %s, type: %d, ctrl_model: %d", it.second->at(i).saddr, it.second->at(i).desc, it.second->at(i).type, it.second->at(i).ctrl_model); + } + } +} + +stru_mms_cfg *mms_cfg_ptr_get(void) +{ + return &g_cfg; +} \ No newline at end of file diff --git a/test/file/MMS/PCS.icd b/test/config/MMS/PCS.icd similarity index 100% rename from test/file/MMS/PCS.icd rename to test/config/MMS/PCS.icd diff --git a/test/config/MMS/mms_s.xml b/test/config/MMS/mms_s.xml new file mode 100644 index 0000000..b2f616a --- /dev/null +++ b/test/config/MMS/mms_s.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/file/MMS/prj.xml b/test/config/MMS/prj.xml similarity index 100% rename from test/file/MMS/prj.xml rename to test/config/MMS/prj.xml