<修改> 1、增加mms服务端配置文件,并解析;

2、增加mms服务端配置信息的处理;
3、调整mms配置文件的目录
This commit is contained in:
ypc 2026-06-04 13:13:33 +08:00
parent 15ecc786bc
commit 3743b69ef2
15 changed files with 728 additions and 297 deletions

View File

@ -146,7 +146,7 @@ typedef struct
std::string saddr; std::string saddr;
uint8_t status; uint8_t status;
uint32_t sec; uint32_t sec;
uint16_t ums; uint16_t ms;
}stru_dc_soe; }stru_dc_soe;
typedef struct typedef struct

View File

@ -106,67 +106,49 @@ extern "C" {
#define MMS_S_PARAM_MAX 16 #define MMS_S_PARAM_MAX 16
typedef void (*mms_s_value_update_cb)(const char * saddr, const char * val);
/** /**
* // * @brief
* @field saddr IEC61850 sAddr * @param cb
* @field desc
* @field type DATA_TYPE_*
* @field ctrl_model
*/ */
void mms_s_value_update_register(mms_s_value_update_cb *cb);
typedef struct typedef struct
{ {
char saddr[MMS_S_STR_LEN]; char saddr[MMS_S_STR_LEN];
char desc[MMS_S_STR_LEN]; char desc[MMS_S_STR_LEN];
uint8_t type; uint8_t type;
uint8_t ctrl_model; uint8_t ctrl_model;
}stru_mms_s_param_base; }stru_mms_s_signal_base;
/**
*
* @field base saddr / desc / type
* @field data
*/
typedef struct typedef struct
{ {
stru_mms_s_param_base base; stru_mms_s_signal_base base;
void *data; void *p_data;
}stru_mms_s_setting; }stru_mms_s_setting;
/** 定值回调函数类型:当定值被写入时调用 */
typedef void (*mms_s_setting_cb)(stru_mms_s_setting *p_setting, const char *p_data); 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 typedef struct
{ {
stru_mms_s_param_base base; stru_mms_s_signal_base base;
uint8_t param_num; uint8_t param_num;
void *data[MMS_S_PARAM_MAX]; void *p_data[MMS_S_PARAM_MAX];
}stru_mms_s_param; }stru_mms_s_param;
/** 参数回调函数类型:当参数区切换或被确认时调用 */
typedef void (*mms_s_param_cb)(stru_mms_s_param *p_param, const char *p_data, int setting_zone); 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 typedef struct
{ {
char saddr[MMS_S_STR_LEN]; stru_mms_s_signal_base base;
char desc[MMS_S_STR_LEN]; void *p_data;
uint8_t ctrl_model;
}stru_mms_s_control; }stru_mms_s_control;
/** 控制操作回调函数类型:当控制命令被执行时调用 */
typedef void (*mms_s_control_cb)(stru_mms_s_control *p_control, uint8_t state); typedef void (*mms_s_control_cb)(stru_mms_s_control *p_control, uint8_t state);

View File

@ -6,7 +6,7 @@
* Direct Operate * Direct Operate
* *
* *
* - vec_control : mms_s_control_register() * - g_vec_control : mms_s_control_register()
* - cb_control : * - cb_control :
* *
* *
@ -29,7 +29,7 @@
#include "mms_s.h" #include "mms_s.h"
/** 外部注册的控制对象列表 */ /** 外部注册的控制对象列表 */
LOCAL std::vector<stru_mms_s_control> vec_control; LOCAL std::vector<stru_mms_s_control> g_vec_control;
/** 控制操作回调函数 */ /** 控制操作回调函数 */
LOCAL mms_s_control_cb cb_control = NULL; 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; DataAttribute *stVal = it->p_all_do->map_all_da["stVal"]->DA;
std::string saddr = it->p_all_do->map_all_da["stVal"]->DA->sAddr; std::string saddr = it->p_all_do->map_all_da["stVal"]->DA->sAddr;
for(std::vector<stru_mms_s_control>::iterator it_control = vec_control.begin(); it_control != vec_control.end(); ++it_control) for(std::vector<stru_mms_s_control>::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) 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; return -1;
} }
vec_control.clear(); g_vec_control.clear();
vec_control.reserve(num); g_vec_control.reserve(num);
for(uint16_t i = 0; i < num; ++i) 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) if(NULL != cb)
@ -285,9 +285,9 @@ int control_init(IedServer server, stru_icd &icd)
return -1; 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; return 0;
} }

View File

@ -5,7 +5,7 @@
* @details Setting Group * @details Setting Group
* *
* *
* - vec_params : param_num * - g_vec_params : param_num
* - g_param_cb : * - g_param_cb :
* *
* FC=SG vs FC=SE * FC=SG vs FC=SE
@ -26,7 +26,7 @@
#include "myMms_s.h" #include "myMms_s.h"
#include "mms_s_param.h" #include "mms_s_param.h"
LOCAL std::vector<stru_mms_s_param> vec_params; LOCAL std::vector<stru_mms_s_param> g_vec_params;
LOCAL mms_s_param_cb g_param_cb = NULL; 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 * SG DA
* *
* vec_params data[actSG-1] sAddr+"_SG" * g_vec_params data[actSG-1] sAddr+"_SG"
* *
* *
* @param ld * @param ld
@ -140,7 +140,7 @@ LOCAL void param_load_active_sg_values(stru_LDevice &ld, int actSG)
return; return;
} }
for(std::vector<stru_mms_s_param>::iterator it_param = vec_params.begin(); it_param != vec_params.end(); it_param++) for(std::vector<stru_mms_s_param>::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"; 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); LOG_E("param_num %d is not enough for saddr %s, actSG %d", it_param->param_num, saddr.c_str(), actSG);
continue; 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()) 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<stru_mms_s_param>::iterator it_param = vec_params.begin(); it_param != vec_params.end(); it_param++) for(std::vector<stru_mms_s_param>::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"; 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); LOG_E("param_num %d is not enough for saddr %s, editSG %d", it_param->param_num, saddr.c_str(), editSG);
continue; 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()) 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<stru_mms_s_param>::iterator it_param = vec_params.begin(); it_param != vec_params.end(); it_param++) for(std::vector<stru_mms_s_param>::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_sg = std::string(it_param->base.saddr) + "_SG";
std::string saddr_se = std::string(it_param->base.saddr) + "_SE"; 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() 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; 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 &param = vec_params[i]; stru_mms_s_param &param = g_vec_params[i];
printf("saddr %s, desc %s, type %d\n", param.base.saddr, param.base.desc, param.base.type); 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++) 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("index %d, val %s\n", j, val.c_str());
} }
printf("\n"); 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; return -1;
} }
vec_params.clear(); g_vec_params.clear();
vec_params.reserve(num); g_vec_params.reserve(num);
for(uint16_t i = 0; i < num; i++) 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) 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) 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; return 0;
} }

View File

@ -29,7 +29,7 @@
#include "mms_s_setting.h" #include "mms_s_setting.h"
LOCAL std::vector<stru_mms_s_setting> vec_settings; LOCAL std::vector<stru_mms_s_setting> g_vec_settings;
LOCAL mms_s_setting_cb cb_setting = NULL; 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) LOCAL void setting_value_init(IedServer server, stru_icd &icd)
{ {
for(std::vector<stru_mms_s_setting>::iterator it = vec_settings.begin(); it != vec_settings.end(); it++) for(std::vector<stru_mms_s_setting>::iterator it = g_vec_settings.begin(); it != g_vec_settings.end(); it++)
{ {
std::string sAddr = it->base.saddr; 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()) 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); LOG_I("da name: %s, sAddr: %s, fc %d", dataAttribute->name, dataAttribute->sAddr, dataAttribute->fc);
} }
for(std::vector<stru_mms_s_setting>::iterator it = vec_settings.begin(); it != vec_settings.end(); it++) for(std::vector<stru_mms_s_setting>::iterator it = g_vec_settings.begin(); it != g_vec_settings.end(); it++)
{ {
std::string sAddr = it->base.saddr; 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) 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()) 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() 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", LOG_I("saddr %s, desc %s, type %d",
setting.base.saddr, setting.base.desc, setting.base.type); 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; return -1;
} }
vec_settings.clear(); g_vec_settings.clear();
vec_settings.reserve(num); g_vec_settings.reserve(num);
for(int i = 0; i < num; i++) 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) 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) 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; return 0;
} }

View File

@ -21,154 +21,152 @@
* - 0 * - 0
*/ */
#include "myMms_s.h"
#include "mms_s_value.h" #include "mms_s_value.h"
// ==================== 值更新回调(当前 Unused预留给 mms_s_values_update ==================== // ==================== 值更新回调(当前 Unused预留给 mms_s_values_update ====================
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);
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);
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);
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);
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);
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);
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);
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);
LOCAL struct
typedef void (*value_update_cb)(IedServer server, DataAttribute *da, std::string val);
LOCAL std::map<DataAttributeType, value_update_cb> g_iec61850s_value_update_cb_map =
{ {
const char *btype; {IEC61850_BOOLEAN, model_da_value_update_Boolean},
void (*value_update_cb)(IedServer server, DataAttribute *da, void *value); {IEC61850_INT8, NULL},
}g_iec61850s_value_update_cb[] = {IEC61850_INT16, NULL},
{ {IEC61850_INT32, model_da_value_update_INT32},
{"BOOLEAN", model_da_value_update_Boolean}, {IEC61850_INT64, NULL},
{"INT8", NULL}, {IEC61850_INT128, NULL},
{"INT16", NULL}, {IEC61850_INT8U, NULL},
{"INT32", model_da_value_update_INT32}, {IEC61850_INT16U, NULL},
{"INT64", NULL}, {IEC61850_INT32U, model_da_value_update_INT32U},
{"INT128", NULL}, {IEC61850_FLOAT32, model_da_value_update_FLOAT32},
{"INT8U", NULL}, {IEC61850_FLOAT64, NULL},
{"INT16U", NULL}, {IEC61850_ENUMERATED, model_da_value_update_Enum},
{"INT32U", model_da_value_update_INT32U}, {IEC61850_OCTET_STRING_64, NULL},
{"FLOAT32", model_da_value_update_FLOAT32}, {IEC61850_OCTET_STRING_6, NULL},
{"FLOAT64", NULL}, {IEC61850_OCTET_STRING_8, NULL},
{"Enum", model_da_value_update_Enum}, {IEC61850_VISIBLE_STRING_32, model_da_value_update_Visible_String},
{"Octet64", NULL}, {IEC61850_VISIBLE_STRING_64, NULL},
{"Octet6", NULL}, {IEC61850_VISIBLE_STRING_65, NULL},
{"Octet8", NULL}, {IEC61850_VISIBLE_STRING_129, NULL},
{"VisString32", model_da_value_update_Visible_String}, {IEC61850_VISIBLE_STRING_255, NULL},
{"VisString64", model_da_value_update_Visible_String}, {IEC61850_UNICODE_STRING_255, model_da_value_update_Unicode_String},
{"VisString65", model_da_value_update_Visible_String}, {IEC61850_TIMESTAMP, model_da_value_update_timesramp},
{"VisString129", model_da_value_update_Visible_String}, {IEC61850_QUALITY, NULL},
{"VisString255", model_da_value_update_Visible_String}, {IEC61850_CHECK, NULL},
{"Unicode255", model_da_value_update_Unicode_String}, {IEC61850_CODEDENUM, NULL},
{"Timestamp", model_da_value_update_timesramp}, {IEC61850_GENERIC_BITSTRING, NULL},
{"Quality", NULL}, {IEC61850_CONSTRUCTED, NULL},
{"Check", NULL}, {IEC61850_ENTRY_TIME, NULL},
{"CodedEnum", NULL}, {IEC61850_PHYCOMADDR, NULL},
{"BitString", NULL}, {IEC61850_CURRENCY, NULL},
{"Struct", NULL}, {IEC61850_OPTFLDS, NULL},
{"EntryTime", NULL}, {IEC61850_TRGOPS, NULL},
{"PhyComAddr", NULL}, {IEC61850_DBPOS, NULL},
{"Currency", NULL},
{"OptFlds", NULL},
{"TrgOps", NULL},
{"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 */ /** 更新 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; return;
} }
int int_value = atoi((char*)value);
if(int_value == 0) if(val == "false" || val == "0")
{ {
IedServer_updateBooleanAttributeValue(server, da, false); IedServer_updateBooleanAttributeValue(server, da, false);
} }
else if(int_value == 1) else if(val == "true" || val == "1")
{ {
IedServer_updateBooleanAttributeValue(server, da, true); IedServer_updateBooleanAttributeValue(server, da, true);
} }
else else
{ {
LOG_E("Invalid boolean value %s", (char *)value); LOG_E("Invalid boolean value %s", val.c_str());
} }
} }
/** 更新 INT32 属性值 */ /** 更新 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; return;
} }
IedServer_updateInt32AttributeValue(server, da, atoi((char*)value)); IedServer_updateInt32AttributeValue(server, da, atoi(val.c_str()));
} }
/** 更新 UINT32 属性值 */ /** 更新 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; return;
} }
IedServer_updateUnsignedAttributeValue(server, da, atoi((char*)value)); IedServer_updateUnsignedAttributeValue(server, da, atoi(val.c_str()));
} }
/** 更新 FLOAT32 属性值 */ /** 更新 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; return;
} }
IedServer_updateFloatAttributeValue(server, da, atof((char*)value)); IedServer_updateFloatAttributeValue(server, da, atof(val.c_str()));
} }
/** 更新 Enum 属性值(直接设置 mmsValue */ /** 更新 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; return;
} }
LOG_I("da %p, name %s, value %d", da, da->name, *(int *)value); LOG_I("da %p, name %s, value %d", da, da->name, atoi(val.c_str()));
da->mmsValue = MmsValue_newIntegerFromInt32(*(int *)value); da->mmsValue = MmsValue_newIntegerFromInt32(atoi(val.c_str()));
} }
/** 更新 VisibleString 属性值 */ /** 更新 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; return;
} }
IedServer_updateVisibleStringAttributeValue(server, da, (char*)value); IedServer_updateVisibleStringAttributeValue(server, da, (char*)val.c_str());
} }
/** 更新 Unicode String 属性值 */ /** 更新 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; return;
} }
IedServer_updateAttributeValue(server, da, MmsValue_newMmsString((char*)value)); IedServer_updateAttributeValue(server, da, MmsValue_newMmsString((char*)val.c_str()));
} }
/** 更新 Timestamp 属性值(设为当前毫秒时间) */ /** 更新 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) if(NULL == server || NULL == da)
{ {
@ -182,14 +180,14 @@ LOCAL void model_da_value_update_timesramp(IedServer server, DataAttribute *da,
// ==================== 值初始化回调mms_s_values_init 使用) ==================== // ==================== 值初始化回调mms_s_values_init 使用) ====================
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);
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);
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);
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);
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);
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);
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);
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);
/** /**
* bType DA * bType DA
@ -197,11 +195,10 @@ LOCAL void mms_s_da_value_init_Dbpos(DataAttribute *da, void *value);
* bType MmsValue DA * bType MmsValue DA
* NULL libiec61850 * NULL libiec61850
*/ */
LOCAL struct
{ typedef void (*value_init_cb)(DataAttribute *da, std::string val);
const char *bType;
void (*value_init)(DataAttribute *da, void *value); LOCAL std::map<std::string, value_init_cb> g_iec61850s_value_init_cb_map =
}g_iec61850s_value_init_cb[] =
{ {
{"BOOLEAN", mms_s_da_value_init_BOOLEAN}, {"BOOLEAN", mms_s_da_value_init_BOOLEAN},
{"INT8", NULL}, {"INT8", NULL},
@ -238,129 +235,127 @@ LOCAL struct
{"Dbpos", mms_s_da_value_init_Dbpos}, {"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 */ /** 初始化 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; 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); 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); da->mmsValue = MmsValue_newBoolean(true);
} }
} }
/** 初始化 INT32根据 val 字符串创建 MmsValue */ /** 初始化 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; return;
} }
if(value == NULL || strlen((char*)value) == 0) if(val == "")
{ {
da->mmsValue = MmsValue_newIntegerFromInt32(0); da->mmsValue = MmsValue_newIntegerFromInt32(0);
} }
else else
{ {
da->mmsValue = MmsValue_newIntegerFromInt32(atoi((char*)value)); da->mmsValue = MmsValue_newIntegerFromInt32(atoi(val.c_str()));
} }
} }
/** 初始化 UINT32根据 val 字符串创建 MmsValue */ /** 初始化 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; return;
} }
if(value == NULL || strlen((char*)value) == 0) if(val == "")
{ {
da->mmsValue = MmsValue_newUnsignedFromUint32(0); da->mmsValue = MmsValue_newUnsignedFromUint32(0);
} }
else else
{ {
da->mmsValue = MmsValue_newUnsignedFromUint32(atoi((char*)value)); da->mmsValue = MmsValue_newUnsignedFromUint32(atoi(val.c_str()));
} }
} }
/** 初始化 FLOAT32根据 val 字符串创建 MmsValue */ /** 初始化 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; return;
} }
if(value == NULL || strlen((char*)value) == 0) if(val == "")
{ {
da->mmsValue = MmsValue_newFloat(0.0); da->mmsValue = MmsValue_newFloat(0.0);
} }
else else
{ {
da->mmsValue = MmsValue_newFloat(atof((char*)value)); da->mmsValue = MmsValue_newFloat(atof(val.c_str()));
} }
} }
/** 初始化 VisibleString根据 val 字符串创建 MmsValue */ /** 初始化 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; return;
} }
if(value == NULL || strlen((char*)value) == 0) if(val == "")
{ {
da->mmsValue = MmsValue_newVisibleString(""); da->mmsValue = MmsValue_newVisibleString("");
} }
else else
{ {
da->mmsValue = MmsValue_newVisibleString((char*)value); da->mmsValue = MmsValue_newVisibleString(val.c_str());
} }
} }
/** 初始化 Unicode String根据 val 字符串创建 MmsValue */ /** 初始化 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; return;
} }
if(value == NULL || strlen((char*)value) == 0) if(val == "")
{ {
da->mmsValue = MmsValue_newMmsString(""); da->mmsValue = MmsValue_newMmsString("");
} }
else else
{ {
da->mmsValue = MmsValue_newMmsString((char*)value); da->mmsValue = MmsValue_newMmsString(val.c_str());
} }
} }
/** 初始化 Timestamp设为当前毫秒时间 */ /** 初始化 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; return;
} }
@ -371,23 +366,23 @@ LOCAL void mms_s_da_value_init_Timestamp(DataAttribute *da, void *value)
* Dbpos * Dbpos
* val=0 INTERMEDIATE_STATE, 1 OFF, 2 ON, 3/ BAD_STATE * 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; return;
} }
Dbpos pos = DBPOS_INTERMEDIATE_STATE; Dbpos pos = DBPOS_INTERMEDIATE_STATE;
if(value == NULL || strlen((char*)value) == 0) if(val == "")
{ {
pos = DBPOS_INTERMEDIATE_STATE; pos = DBPOS_INTERMEDIATE_STATE;
} }
else else
{ {
int i = atoi((char*)value); int i = atoi(val.c_str());
if(i == 0) if(i == 0)
{ {
pos = DBPOS_INTERMEDIATE_STATE; 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()) 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 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) LOG_E("BDAType %s not found in ICD", p_all_da->bType.c_str());
{ return;
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()); 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); 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<std::string, stru_saddr_point> 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;
} }

View File

@ -1,6 +1,7 @@
#include <mutex> #include <mutex>
#include <queue> #include <queue>
#include <vector> #include <vector>
#include <sys/time.h>
#include "dc_event.h" #include "dc_event.h"
#include "myLog.h" #include "myLog.h"
@ -20,6 +21,15 @@ LOCAL std::queue<stru_dc_fault> g_fault_queue;
LOCAL std::vector<dc_queue_pop_cb> g_fault_queue_pop_cbs; LOCAL std::vector<dc_queue_pop_cb> 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) int dc_disturb_dd_register_queue_pop(dc_queue_pop_cb cb)
{ {
if(!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) 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<std::mutex> lock(g_disturb_dd_mutex); std::lock_guard<std::mutex> lock(g_disturb_dd_mutex);
g_disturb_dd_queue.push(dd);
g_disturb_dd_queue.push(local_dd);
return 0; 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) 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<std::mutex> lock(g_soe_mutex); std::lock_guard<std::mutex> lock(g_soe_mutex);
g_soe_queue.push(soe); g_soe_queue.push(local_soe);
return 0; 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) 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<std::mutex> lock(g_fault_mutex); std::lock_guard<std::mutex> lock(g_fault_mutex);
g_fault_queue.push(fault); g_fault_queue.push(local_fault);
return 0; return 0;
} }

View File

@ -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) 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", 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); soe.saddr.c_str(), soe.status, soe.sec, soe.ms);
UserWriteSoeEvent(i, soe.status, soe.sec, soe.ums); 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.uiInfoAddr = i;
soe_info.ucStatus = fault.vec_soe[0].status; soe_info.ucStatus = fault.vec_soe[0].status;
soe_info.uiSeconds = fault.vec_soe[0].sec; 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; break;
} }
} }

View File

@ -7,7 +7,7 @@
LOCAL void mms_event_back(void *arg, int ret); 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 typedef struct
{ {

View File

@ -0,0 +1,28 @@
#pragma once
#include <string>
#include <vector>
#include <map>
#include "myBase.h"
#include "myMms_s.h"
#include "tinyxml2.h"
typedef struct
{
std::vector<stru_mms_s_signal_base> vec_st;
std::vector<stru_mms_s_signal_base> vec_mx;
std::vector<stru_mms_s_signal_base> vec_co;
std::vector<stru_mms_s_signal_base> vec_ao;
std::vector<stru_mms_s_signal_base> 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);

View File

@ -3,36 +3,96 @@
#include "myLog.h" #include "myLog.h"
#include "myCmd.h" #include "myCmd.h"
#include "myDatacenter.h" #include "myDatacenter.h"
#include "parse_xml.h"
LOCAL std::vector<stru_mms_s_control> vec_control = typedef struct
{ {
{"iec61850m.prj.co.0", "遥控01", 4}, stru_mms_s_signal_base base;
{"iec61850m.prj.co.1", "遥控02", 4}, void *p_data;
{"iec61850m.prj.co.2", "遥控03", 4}, }stru_local_st_mx;
{"iec61850m.prj.co.3", "遥控04", 4},
};
LOCAL std::vector<stru_mms_s_setting> vec_setting = LOCAL std::vector<stru_local_st_mx> g_vec_st = {};
LOCAL std::vector<stru_local_st_mx> g_vec_mx = {};
LOCAL std::vector<stru_mms_s_control> g_vec_control = {};
LOCAL std::vector<stru_mms_s_setting> g_vec_setting = {};
LOCAL std::vector<stru_mms_s_param> 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}, LOG_E("p_data or p_last_data is NULL");
.data = NULL, return;
},
{
.base = {.saddr = "iec61850m.prj.ao.1", .desc = "参数02", .type = DATA_TYPE_STR},
.data = NULL,
} }
};
LOCAL std::vector<stru_mms_s_param> 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}, LOG_E("val is empty");
.data = NULL, 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<stru_mms_s_signal_base> &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<stru_mms_s_signal_base> &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) if(NULL == p_control)
{ {
@ -40,7 +100,9 @@ void iec61850s_control_callback(stru_mms_s_control *p_control, uint8_t state)
return; 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; uint8_t temp_st = 0;
stru_signal_ctrl ctrl = { 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, .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; 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"); MY_LOG_E("dc_signal_yk_set_status failed");
return; 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; 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"); MY_LOG_E("dc_signal_yk_set_status failed");
return; 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"); MY_LOG_E("dc_signal_yk_set_status failed");
return; 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"); MY_LOG_I("CONTROL_MODEL_STATUS_ONLY");
return; return;
} }
} }
void iec61850s_setting_callback(stru_mms_s_setting *p_setting, const char *p_data) LOCAL int iec61850s_control_signals_init(std::vector<stru_mms_s_signal_base> &vec_co)
{
g_vec_control.clear();
g_vec_control.reserve(vec_co.size());
for(std::vector<stru_mms_s_signal_base>::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) 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<stru_mms_s_signal_base> &vec_ao)
{
g_vec_setting.clear();
g_vec_setting.reserve(vec_ao.size());
for(std::vector<stru_mms_s_signal_base>::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) 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<stru_mms_s_signal_base> &vec_param)
{
g_vec_param.clear();
g_vec_param.reserve(vec_param.size());
for(std::vector<stru_mms_s_signal_base>::iterator it = vec_param.begin(); it != vec_param.end(); ++it)
{
stru_mms_s_param param = {};
param.base = *it;
std::string desc = "";
std::vector<void *> 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) 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_dbg_switch(true);
mms_s_file_path_set("/mnt/RTU/test/"); 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; return 0;
} }
int app_iec61850s_init2(void *arg) int app_iec61850s_init2(void *arg)
{ {
for(std::vector<stru_mms_s_setting>::iterator it = vec_setting.begin(); it != vec_setting.end(); ++it) if(0 != iec61850s_signals_init())
{ {
std::string desc = ""; MY_LOG_E("iec61850s_signals_init failed");
uint8_t data_type = 0; return -1;
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<stru_mms_s_param>::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<void *> 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];
}
} }
mms_s_setting_register(vec_setting.data(), vec_setting.size(), iec61850s_setting_callback); if(0 != mms_s_init("/mnt/RTU/test/config/MMS/PCS.icd", 102))
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))
{ {
MY_LOG_E("mms_s_init failed"); MY_LOG_E("mms_s_init failed");
return -1; return -1;

View File

@ -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<std::string, std::vector<stru_mms_s_signal_base> *> 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<std::string, std::vector<stru_mms_s_signal_base> *>::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<std::string, std::vector<stru_mms_s_signal_base> *> 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;
}

30
test/config/MMS/mms_s.xml Normal file
View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<St>
<Signal no="0" link="iec61850m.prj.st.0" desc="遥信01" />
<Signal no="1" link="iec61850m.prj.st.1" desc="遥信02" />
<Signal no="2" link="iec61850m.prj.st.2" desc="遥信03" />
<Signal no="3" link="iec61850m.prj.st.3" desc="遥信04" />
<Signal no="4" link="iec61850m.prj.st.4" desc="低频保护软压板" />
</St>
<Mx>
<Signal no="0" link="iec61850m.prj.mx.0" desc="遥测01" />
<Signal no="1" link="iec61850m.prj.mx.1" desc="遥测02" />
<Signal no="2" link="iec61850m.prj.mx.2" desc="遥测03" />
<Signal no="3" link="iec61850m.prj.mx.3" desc="遥测04" />
</Mx>
<Co>
<Signal no="0" link="iec61850m.prj.co.0" desc="遥控01"/>
<Signal no="1" link="iec61850m.prj.co.1" desc="遥控02"/>
<Signal no="2" link="iec61850m.prj.co.2" desc="遥控03"/>
<Signal no="3" link="iec61850m.prj.co.3" desc="遥控04"/>
<Signal no="4" link="iec61850m.prj.co.4" desc="低频保护软压板"/>
</Co>
<Ao>
<Signal no="0" link="iec61850m.prj.ao.0" desc="参数01" />
<Signal no="1" link="iec61850m.prj.ao.1" desc="参数02" />
</Ao>
<Param>
<Signal no="0" link="iec61850m.prj.param.0" desc="定值01" />
</Param>
</Root>