新增61850的mms服务端程序;

调整数据中心部分接口
This commit is contained in:
ypc 2026-05-27 09:14:19 +08:00
parent 719bf36004
commit 04976dd01b
32 changed files with 6091 additions and 66 deletions

131
release/inc/myMms_s.h Normal file
View File

@ -0,0 +1,131 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifndef DATA_TYPE_B
#define DATA_TYPE_B 1
#endif /* DATA_TYPE_B */
#ifndef DATA_TYPE_S8
#define DATA_TYPE_S8 43
#endif /* DATA_TYPE_S8 */
#ifndef DATA_TYPE_U8
#define DATA_TYPE_U8 32
#endif /* DATA_TYPE_U8 */
#ifndef DATA_TYPE_S16
#define DATA_TYPE_S16 33
#endif /* DATA_TYPE_S16 */
#ifndef DATA_TYPE_U16
#define DATA_TYPE_U16 45
#endif /* DATA_TYPE_U16 */
#ifndef DATA_TYPE_S32
#define DATA_TYPE_S32 2
#endif /* DATA_TYPE_S32 */
#ifndef DATA_TYPE_U32
#define DATA_TYPE_U32 35
#endif /* DATA_TYPE_U32 */
#ifndef DATA_TYPE_L64
#define DATA_TYPE_L64 36
#endif /* DATA_TYPE_L64 */
#ifndef DATA_TYPE_UL64
#define DATA_TYPE_UL64 37
#endif /* DATA_TYPE_UL64 */
#ifndef DATA_TYPE_F32
#define DATA_TYPE_F32 38
#endif /* DATA_TYPE_F32 */
#ifndef DATA_TYPE_D64
#define DATA_TYPE_D64 39
#endif /* DATA_TYPE_D64 */
#ifndef DATA_TYPE_IP
#define DATA_TYPE_IP 100
#endif /* DATA_TYPE_IP */
#ifndef DATA_TYPE_MAC
#define DATA_TYPE_MAC 101
#endif /* DATA_TYPE_MAC */
#ifndef DATA_TYPE_C8
#define DATA_TYPE_C8 102
#endif /* DATA_TYPE_C8 */
#ifndef DATA_TYPE_C32
#define DATA_TYPE_C32 103
#endif /* DATA_TYPE_C32 */
#ifndef DATA_TYPE_C64
#define DATA_TYPE_C64 104
#endif /* DATA_TYPE_C64 */
#ifndef DATA_TYPE_C128
#define DATA_TYPE_C128 105
#endif /* DATA_TYPE_C128 */
#ifndef DATA_TYPE_C1
#define DATA_TYPE_C1 106
#endif /* DATA_TYPE_C1 */
#ifndef DATA_TYPE_STR
#define DATA_TYPE_STR 107
#endif /* DATA_TYPE_STR */
#define MMS_S_STR_LEN 64
#define MMS_S_PARAM_MAX 16
typedef struct
{
char saddr[MMS_S_STR_LEN];
char desc[MMS_S_STR_LEN];
uint8_t type;
uint8_t ctrl_model;
// float min;
// float max;
// float step;
// char unit[MMS_S_STR_LEN];
}stru_mms_s_param_base;
// 定值仅支持一个参数
typedef struct
{
stru_mms_s_param_base base;
void *data;
}stru_mms_s_setting;
typedef void (*mms_s_setting_cb)(stru_mms_s_setting *p_setting, const char *p_data);
// 参数支持多个值
typedef struct
{
stru_mms_s_param_base base;
uint8_t param_num;
void *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);
typedef struct
{
char saddr[MMS_S_STR_LEN];
char desc[MMS_S_STR_LEN];
uint8_t ctrl_model;
}stru_mms_s_control;
typedef void (*mms_s_control_cb)(stru_mms_s_control *p_control, uint8_t state);
int mms_s_init(const char* icd_path, int port);
void mms_s_dbg_switch(bool on);
int mms_s_control_register(stru_mms_s_control *p_control, uint16_t num, mms_s_control_cb cb);
int mms_s_setting_register(stru_mms_s_setting *p_setting, uint16_t num, mms_s_setting_cb cb);
int mms_s_param_register(stru_mms_s_param *p_param, uint16_t num, mms_s_param_cb cb);
int mms_s_file_path_set(const char* file_path);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -61,6 +61,7 @@ typedef enum
ENUM_APP_SELF_PTL, // icp67应用
ENUM_APP_WEB_SERVER, // web服务器应用
ENUM_APP_IEC61850M, // iec61850m应用
ENUM_APP_IEC61850S, // iec61850s应用
ENUM_APP_MAX
}enum_app;
@ -225,6 +226,13 @@ extern int app_iec61850m_init1(void *arg);
extern int app_iec61850m_init2(void *arg);
extern void *app_iec61850m(void *arg);
// iec61850s应用初始化与线程函数声明
extern int app_iec61850s_init1(void *arg);
extern int app_iec61850s_init2(void *arg);
extern void *app_iec61850s(void *arg);
// icp67线程设置通道类型
void self_ptl_set_interface(uint32_t interface);
@ -343,13 +351,13 @@ int dc_signal_out(const std::string &saddr, const std::string &desc, uint8_t dat
int dc_signal_out_with_callback(const std::string &saddr, const std::string &desc, uint8_t data_type, void *p_data, out_signal_change_cb cb);
// 数据中心in信号注册并链接out信号接口
int dc_signal_in(const std::string &saddr, const std::string &desc, const std::string &link_saddr, uint8_t data_type, void **p_data);
int dc_signal_in(const std::string &saddr, const std::string &desc, const std::string &link_saddr, void **p_data);
int dc_signal_in_with_callback(const std::string &saddr, const std::string &desc, const std::string &link_saddr, uint8_t data_type, void **p_data, out_signal_change_cb cb);
int dc_signal_in_with_callback(const std::string &saddr, const std::string &desc, const std::string &link_saddr, void **p_data, out_signal_change_cb cb);
int dc_signal_ao(const std::string &saddr, const std::string &desc, uint8_t data_type, const stru_signal_param &param, uint8_t ctrl_type, void *p_data, void *p_default_data, signal_change_cb cb);
int dc_signal_ao_link_with_callback(const std::string &saddr, uint8_t data_type, void **p_data, signal_change_cb cb);
int dc_signal_ao_link_with_callback(const std::string &saddr, void **p_data, signal_change_cb cb);
int dc_signal_ao_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, void *p_data);
@ -359,7 +367,7 @@ int dc_signal_ao_set_val_without_check(const std::string &saddr, uint8_t data_ty
int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t data_type, const stru_signal_param &param, uint8_t ctrl_type, std::vector<void *> &vec_p_data, std::vector<void *> &vec_p_default_data, signal_change_cb cb);
// 数据中心参数链接信号接口
int dc_signal_param_link_with_callback(const std::string &saddr, uint8_t data_type, std::vector<void *> &vec_p_data, signal_change_cb cb);
int dc_signal_param_link_with_callback(const std::string &saddr, std::vector<void *> &vec_p_data, signal_change_cb cb);
// 数据中心参数设置接口
int dc_signal_param_set_val(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, uint8_t setting_zone, void *p_data);
@ -370,7 +378,7 @@ int dc_signal_param_set_val_without_check(const std::string &saddr, uint8_t data
int dc_signal_yk(const std::string &saddr, const std::string &desc, uint8_t data_type, uint8_t ctrl_type, void *p_data, signal_change_cb cb);
// 数据中心遥控信号链接接口
int dc_signal_yk_link_with_callback(const std::string &saddr, uint8_t data_type, void **p_data, signal_change_cb cb);
int dc_signal_yk_link_with_callback(const std::string &saddr, void **p_data, signal_change_cb cb);
// 数据中心遥控控制接口(校验前置,调用前需先调 dc_yk_ctrl_valid)
int dc_signal_yk_set_status(const std::string &saddr, SIGNAL_CTRL_STEP step, stru_signal_ctrl &ctrl, void *p_data);
@ -381,7 +389,7 @@ int dc_get_out_signal_info(const std::string &saddr, std::string &desc, uint8_t
// 数据中心获取in信号信息接口
int dc_get_in_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, std::vector<void *> &vec_p_data);
int dc_get_ao_siganl_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param &param, uint8_t &ctrl_type, std::vector<void *> &vec_p_data, std::vector<void *> &vec_p_default_data);
int dc_get_ao_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param &param, uint8_t &ctrl_type, std::vector<void *> &vec_p_data, std::vector<void *> &vec_p_default_data);
// 数据中心获取参数信号信息接口
int dc_get_param_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param &param, uint8_t &ctrl_type, std::vector<void *> &vec_p_data, std::vector<void *> &vec_p_default_data);

View File

@ -0,0 +1,87 @@
# 包含外部Makefile
include ./../../../linux.mk
ProjectName := libmms_s
DIR := $(realpath $(CURDIR)/..)
LAST_DIR := $(notdir $(DIR))
# 静态库文件目标
OutputFile := $(LIB_REL)/$(ProjectName).a
ArchiveCommand := ar rcs # 静态库打包命令
MakeDirCommand := mkdir -p
OBJ := $(DIR)/$(ProjectName)/obj
SRC := $(SRC_ROOT_DIR)/$(LAST_DIR)/$(ProjectName)/src
INC := $(SRC_ROOT_DIR)/$(LAST_DIR)/$(ProjectName)/inc
INC += $(REL_INC)/iec61850_inc
# print_dir:
# @echo "Shell层面打印DIR: $(SRC_ROOT_DIR) $(OBJ) $(SRC) $(INC) "
# 定义源文件和对象文件
SOURCES := $(wildcard $(SRC)/*.c) $(wildcard $(SRC)/*.cpp)
OBJECTS := $(patsubst $(SRC)/%.c, $(OBJ)/%.o,$(filter %.c,$(SOURCES)))
OBJECTSCPP := $(patsubst $(SRC)/%.cpp, $(OBJ)/%.o,$(filter %.cpp,$(SOURCES)))
ALL_OBJECTS := $(OBJECTS) $(OBJECTSCPP)
# 编译选项
APP_C_FLAGS := $(C_FLAGS)
APP_C_FLAGS += -I $(INC) -g
APP_C_FLAGS += -O0
# 伪目标
.PHONY : all clean veryclean rebuild
# 默认目标
all: $(OutputFile)
# 构建静态库
$(OutputFile): $(ALL_OBJECTS)
@$(MakeDirCommand) $(dir $@)
$(ArchiveCommand) $@ $^
@echo "Static library built: $@"
# 重新构建
rebuild: veryclean all
# 清理
clean:
rm -f $(OBJ)/*.o
rm -f $(OBJ)/*.d
rm -f $(OutputFile)
rm -f ./out/*.*
# 非常彻底的清理
veryclean: clean
rm -f ./out/$(OutputFile)
rm -f $(SRC)/*.bak
rm -f $(INC)/*.bak
# C对象文件规则
$(OBJECTS): $(OBJ)/%.o: $(SRC)/%.c
@mkdir -p $(dir $@)
$(CC) $(APP_C_FLAGS) -o $@ -c $<
# C++对象文件规则
$(OBJECTSCPP): $(OBJ)/%.o: $(SRC)/%.cpp
@mkdir -p $(dir $@)
$(CPP) $(APP_C_FLAGS) -o $@ -c $<
# 可选:生成依赖文件(用于自动重新编译)
# -include $(ALL_OBJECTS:.o=.d)
# C依赖文件规则
$(OBJ)/%.d: $(SRC)/%.c
@mkdir -p $(dir $@)
$(CC) $(APP_C_FLAGS) -MM -MT '$(OBJ)/$*.o' $< > $@
# C++依赖文件规则
$(OBJ)/%.d: $(SRC)/%.cpp
@mkdir -p $(dir $@)
$(CPP) $(APP_C_FLAGS) -MM -MT '$(OBJ)/$*.o' $< > $@

View File

@ -5,6 +5,7 @@ SUBDIRS += ./libicp67
SUBDIRS += ./libmms_m
SUBDIRS += ./libmms_s
SUBDIRS += ./libmoongoose

View File

@ -15,8 +15,8 @@ MakeDirCommand := mkdir -p
# 静态库链接(注意顺序很重要,被依赖的库放在后面)
# Libs := -lcom_channel -lcom_scan -liec -lself_ptl -lfunc -ltask -lcomm -lshell -lpthread
Libs := -lcom_channel -lcom_scan -liec -liec61850m -lself_ptl -lweb_server -ldatacenter
Libs += -l60870 -licp67 -lmms_m -lmoongoose
Libs := -lcom_channel -lcom_scan -liec -liec61850m -liec61850s -lself_ptl -lweb_server -ldatacenter
Libs += -l60870 -licp67 -lmms_m -lmms_s -lmoongoose
Libs += -liec61850
Libs += -lmy_xxhash -lcmd -lmd5 -lxml -lcJSON -lcomm -ltask -lfunc
Libs += -lpthread

View File

@ -0,0 +1,85 @@
# 包含外部Makefile
include ./../../../linux.mk
ProjectName := libiec61850s
DIR := $(realpath $(CURDIR)/..)
LAST_DIR := $(notdir $(DIR))
# 静态库文件目标
OutputFile := $(LIB_REL)/$(ProjectName).a
ArchiveCommand := ar rcs # 静态库打包命令
MakeDirCommand := mkdir -p
OBJ := $(DIR)/$(ProjectName)/obj
SRC := $(SRC_ROOT_DIR)/$(LAST_DIR)/$(ProjectName)/src
INC := $(SRC_ROOT_DIR)/$(LAST_DIR)/$(ProjectName)/inc
INC += $(REL_INC)/iec61850_inc
# print_dir:
# @echo "Shell层面打印DIR: $(SRC_ROOT_DIR) $(OBJ) $(SRC) $(INC) "
# 定义源文件和对象文件
SOURCES := $(wildcard $(SRC)/*.c) $(wildcard $(SRC)/*.cpp)
OBJECTS := $(patsubst $(SRC)/%.c, $(OBJ)/%.o,$(filter %.c,$(SOURCES)))
OBJECTSCPP := $(patsubst $(SRC)/%.cpp, $(OBJ)/%.o,$(filter %.cpp,$(SOURCES)))
ALL_OBJECTS := $(OBJECTS) $(OBJECTSCPP)
# 编译选项
APP_C_FLAGS := $(C_FLAGS)
APP_C_FLAGS += -I $(INC) -g
APP_C_FLAGS += -O0
# 伪目标
.PHONY : all clean veryclean rebuild
# 默认目标
all: $(OutputFile)
# 构建静态库
$(OutputFile): $(ALL_OBJECTS)
@$(MakeDirCommand) $(dir $@)
$(ArchiveCommand) $@ $^
@echo "Static library built: $@"
# 重新构建
rebuild: veryclean all
# 清理
clean:
rm -f $(OBJ)/*.o
rm -f $(OBJ)/*.d
rm -f $(OutputFile)
rm -f ./out/*.*
# 非常彻底的清理
veryclean: clean
rm -f ./out/$(OutputFile)
rm -f $(SRC)/*.bak
rm -f $(INC)/*.bak
# C对象文件规则
$(OBJECTS): $(OBJ)/%.o: $(SRC)/%.c
@mkdir -p $(dir $@)
$(CC) $(APP_C_FLAGS) -o $@ -c $<
# C++对象文件规则
$(OBJECTSCPP): $(OBJ)/%.o: $(SRC)/%.cpp
@mkdir -p $(dir $@)
$(CPP) $(APP_C_FLAGS) -o $@ -c $<
# 可选:生成依赖文件(用于自动重新编译)
# -include $(ALL_OBJECTS:.o=.d)
# C依赖文件规则
$(OBJ)/%.d: $(SRC)/%.c
@mkdir -p $(dir $@)
$(CC) $(APP_C_FLAGS) -MM -MT '$(OBJ)/$*.o' $< > $@
# C++依赖文件规则
$(OBJ)/%.d: $(SRC)/%.cpp
@mkdir -p $(dir $@)
$(CPP) $(APP_C_FLAGS) -MM -MT '$(OBJ)/$*.o' $< > $@

View File

@ -8,6 +8,7 @@ SUBDIRS += ./libcom_scan
SUBDIRS += ./libdatacenter
SUBDIRS += ./libiec
SUBDIRS += ./libiec61850m
SUBDIRS += ./libiec61850s
SUBDIRS += ./libself_ptl
SUBDIRS += ./libweb_server

View File

@ -0,0 +1,122 @@
/**
* @file mms_s.h
* @brief libmms_s 核心头文件,包含日志宏、全局接口声明
*
* @details 本文件定义了:
* - 终端彩色打印宏(COLOR_RESET / COLOR_RED / COLOR_WHITE)
* - 带时间戳的日志宏(LOG / LOG_I / LOG_E)
* - LOCAL 静态函数宏
* - IED 服务器全局访问接口
* - MMS 数据类型与自定义类型之间的字符串转换函数
*/
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include "mms_s_icd.h"
/* 终端颜色控制 —— 重置 */
#ifndef COLOR_RESET
#define COLOR_RESET "\033[0m"
#endif
/* 终端颜色控制 —— 红色(错误信息) */
#ifndef COLOR_RED
#define COLOR_RED "\033[31m"
#endif
/* 终端颜色控制 —— 白色(普通信息) */
#ifndef COLOR_WHITE
#define COLOR_WHITE "\033[37m"
#endif
/* 获取当前时间字符串,格式:YYYY-MM-DD HH:MM:SS.mmm */
#ifndef __CURRENT_TIME__
#define __CURRENT_TIME__ \
({ \
struct timeval __tv; \
gettimeofday(&__tv, NULL); \
struct tm *__tm = localtime(&__tv.tv_sec); \
static char __buf[84]; \
snprintf(__buf, sizeof(__buf), "%04d-%02d-%02d %02d:%02d:%02d.%03d", \
__tm->tm_year + 1900, __tm->tm_mon + 1, __tm->tm_mday, \
__tm->tm_hour, __tm->tm_min, __tm->tm_sec, (int)(__tv.tv_usec / 1000)); \
__buf; \
})
#endif
/* 从 __FILE__ 宏中提取不含路径的短文件名 */
#ifndef __SHORT_FILE__
#define __SHORT_FILE__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#endif
/*
* 通用日志宏
* @param color 终端颜色(COLOR_WHITE / COLOR_RED)
* @param level 日志级别字符串("INFO" / "ERROR")
* @param fmt 格式化字符串
* @param ... 可变参数
* 输出格式:[level] [时间: 文件名, 行号] 消息内容
*/
#ifndef LOG
#define LOG(color, level, fmt, ...) \
do{\
printf("%s[%s] [%s: %s, %u] " fmt COLOR_RESET "\n", \
color, level, __CURRENT_TIME__, __SHORT_FILE__, __LINE__, ##__VA_ARGS__); \
}while (0)
#endif
/* 信息级别日志(白色) */
#ifndef LOG_I
#define LOG_I(fmt, ...) LOG(COLOR_WHITE, "INFO", fmt, ##__VA_ARGS__)
#endif
/* 错误级别日志(红色) */
#ifndef LOG_E
#define LOG_E(fmt, ...) LOG(COLOR_RED, "ERROR", fmt, ##__VA_ARGS__)
#endif
/* 将函数声明为局部(static)的简便写法 */
#ifndef LOCAL
#define LOCAL static
#endif
/**
* 获取全局 ICD 数据结构指针
* @return stru_icd* ICD 数据结构指针,未初始化时返回 NULL
*/
stru_icd *mms_s_get_icd_ptr();
/**
* 获取全局 IED 服务器指针
* @return IedServer IED 服务器指针,未初始化时返回 NULL
*/
IedServer mms_s_get_ied_server_ptr();
/**
* 获取调试开关状态
* @return true 已开启调试,false 未开启
*/
bool mms_s_dbg_get();
/**
* 将 MMS 类型数据转换为字符串(按 MMS 类型码转换)
* @param p_data 数据指针
* @param type MMS 类型码(MMS_BOOLEAN / MMS_INTEGER / MMS_UNSIGNED / MMS_FLOAT / MMS_VISIBLE_STRING 等)
* @return 转换后的字符串,不支持的类型返回空串
*/
std::string mms_s_get_string_by_mms_type(void *p_data, int type);
/**
* 将数据转换为字符串(按自定义 DATA_TYPE_ 类型码转换)
* @param p_data 数据指针
* @param type 自定义类型码(DATA_TYPE_B / DATA_TYPE_S32 / DATA_TYPE_F32 / DATA_TYPE_STR 等)
* @return 转换后的字符串,不支持的类型返回空串
*/
std::string mms_s_get_string_by_type(void *p_data, int type);

View File

@ -0,0 +1,5 @@
#pragma once
#include "mms_s_icd.h"
int control_init(IedServer server, stru_icd &icd);

View File

@ -0,0 +1,6 @@
#pragma once
#include "mms_s.h"
int file_init(IedServer server);

View File

@ -0,0 +1,269 @@
#pragma once
#include <map>
#include <string>
#include <vector>
#include "iec61850_server.h"
typedef struct
{
std::string desc;
std::string type;
}stru_DO;
typedef struct
{
std::string lnClass;
std::vector<std::string> vec_do;
std::map<std::string, stru_DO> map_do; // key:name
}stru_LNodeType;
typedef struct
{
std::string bType;
std::string type;
std::string dchg;
std::string qchg;
std::string fc;
std::string text;
}stru_DA;
typedef struct
{
std::string cdc;
std::vector<std::string> vec_da;
std::map<std::string, stru_DA> map_da; // key:name
std::vector<std::string> vec_sdo;
std::map<std::string, std::string> map_sdo; // key:name
}stru_DOType;
typedef struct
{
std::string bType;
std::string type;
std::string fc;
std::string dchg;
std::string qchg;
}stru_BDA;
typedef struct
{
std::vector<std::string> vec_bda;
std::map<std::string, stru_BDA> map_bda; // key:name
}stru_DAType;
typedef struct
{
std::vector<int> vec_ord;
std::map<int, std::string> map_enumVal; // key:ord
}stru_EnumType;
typedef struct _all_DA
{
DataAttribute *DA;
std::string bType;
std::string type;
std::string fc;
std::string dchg;
std::string qchg;
std::string text;
std::string sAddr;
std::string val;
std::map<std::string, struct _all_DA *> map_all_da; // key:name
}stru_all_DA;
typedef struct _all_DO
{
DataObject *DO;
std::map<std::string, struct _all_DO *> map_all_sdo; // key:name
std::map<std::string, stru_all_DA *> map_all_da; // key:name
}stru_all_DO;
typedef struct _DAI
{
std::string sAddr;
std::string val;
}stru_DAI;
typedef struct _SDI
{
std::vector<std::string> vec_sdI;
std::map<std::string, struct _SDI> map_sdI; // key:name
std::vector<std::string> vec_daI;
std::map<std::string, stru_DAI> map_daI; // key:name
}stru_SDI;
typedef struct _DOI
{
std::string desc;
std::vector<std::string> vec_sdI;
std::map<std::string, stru_SDI> map_sdI; // key:name
std::vector<std::string> vec_daI;
std::map<std::string, stru_DAI> map_daI; // key:name
}stru_DOI;
typedef struct
{
std::string ldevice_inst;
std::string ln_type;
std::string ln_class;
std::string ln_inst;
std::string ln_prefix;
std::string do_name;
stru_all_DO *p_all_do;
}stru_contorl_DO;
typedef struct
{
LogicalNode *LN;
std::string lnType;
std::string lnClass;
std::string desc;
std::string inst;
std::string prefix;
std::vector<std::string> vec_doI;
std::map<std::string, stru_DOI> map_doI; // key:name
std::map<std::string, stru_all_DO *> map_all_do; // key:name
}stru_LN;
typedef struct
{
DataSetEntry *fcda;
std::string ldInst;
std::string lnClass;
std::string lnInst;
std::string prefix;
std::string doName;
std::string daName;
std::string fc;
}stru_FCDA;
typedef struct
{
DataSet *dataset;
std::string desc;
std::vector<stru_FCDA> vec_fcda;
}stru_DataSet;
typedef struct
{
bool dchg;
bool qchg;
bool dupd;
bool period;
}stru_TrgOps;
typedef struct
{
bool seqNum;
bool timeStamp;
bool dataSet;
bool reasonCode;
bool dataRef;
bool entryID;
bool configRef;
}stru_OptFields;
typedef struct
{
ReportControlBlock *Rcb;
std::string datSet;
int intgPd;
std::string rptID;
int confRev;
bool buffered;
int bufTime;
stru_TrgOps trgOps;
stru_OptFields optFields;
int RptEnabled_max;
}stru_ReportControl;
typedef struct
{
uint8_t actSG;
uint8_t numOfSGs;
}stru_SettingControl;
typedef struct
{
LogicalNode *LLN0;
std::string lnType;
std::string lnClass;
std::vector<std::string> vec_dataset;
std::map<std::string, stru_DataSet> map_dataset; // key:name
std::vector<std::string> vec_reportControl;
std::map<std::string, stru_ReportControl> map_reportControl; // key:name
std::vector<std::string> vec_doI;
std::map<std::string, stru_DOI> map_doI; // key:name
std::map<std::string, stru_all_DO *> map_all_do; // key:name
stru_SettingControl settingControl;
}stru_LN0;
typedef struct
{
LogicalDevice *Ldevice;
SettingGroupControlBlock* sgcb;
stru_LN0 ln0;
std::vector<stru_LN> vec_ln;
}stru_LDevice;
typedef struct
{
ModelNode *node;
}stru_saddr_point;
typedef struct
{
DataAttribute *DA;
DataAttributeType type;
std::string str_val;
int val;
}stru_setting_info;
typedef struct
{
IedModel *model;
std::string name;
std::string desc;
std::string type;
std::vector<std::string> vec_ldevice;
std::map<std::string, stru_LDevice> map_ldevice; // key:inst
std::vector<stru_contorl_DO> vec_control_do;
std::vector<std::string> vec_saddr;
std::map<std::string, stru_saddr_point> map_saddr_point; // key:saddr
std::map<std::string, stru_setting_info> map_setting_info; // key:name
}stru_ied;
typedef struct
{
stru_ied ied;
std::vector<std::string> vec_lnType;
std::map<std::string, stru_LNodeType> map_lnType; // key:id
std::vector<std::string> vec_doType;
std::map<std::string, stru_DOType> map_doType; // key:id
std::vector<std::string> vec_daType;
std::map<std::string, stru_DAType> map_daType; // key:id
std::vector<std::string> vec_enumType;
std::map<std::string, stru_EnumType> map_enumType; // key:id
}stru_icd;
stru_icd *icd_parse(const char *icd_path);
void icd_show(stru_icd &icd);

View File

@ -0,0 +1,6 @@
#pragma once
#include "iec61850_server.h"
#include "mms_s_icd.h"
int model_init(stru_icd &icd);

View File

@ -0,0 +1,5 @@
#pragma once
#include "mms_s.h"
int param_init(IedServer server, stru_icd &icd);

View File

@ -0,0 +1,28 @@
/**
* @file mms_s_setting.h
* @brief IEC 61850 定值(SP)管理初始化接口
*
* @details 定值(Setting,FC=SP)区别于参数(FC=SG/SE),定值不参与定值组切换。
* 本模块负责:
* - 将外部注册的定值数据初始化到 SP 数据属性
* - 安装写访问回调,接收客户端下发的定值修改
* - 写操作时进行范围检查和步长校验
* - 设置 SP 的默认写权限为 DENY,仅注册的 sAddr 允许写入
*/
#pragma once
#include "mms_s.h"
/**
* 初始化定值管理功能
*
* 1. 将注册的定值初始值写入对应 SP DA
* 2. 设置 SP 写权限为 ACCESS_POLICY_DENY
* 3. 为每个注册 sAddr 的 DA 安装写访问处理器(writeAccessHandler)
*
* @param server IED 服务器指针
* @param icd ICD 数据结构引用
* @return 0 成功,-1 失败
*/
int setting_init(IedServer server, stru_icd &icd);

View File

@ -0,0 +1,7 @@
#pragma once
#include "mms_s_icd.h"
#include "mms_s.h"
void mms_s_values_init();
void mms_s_values_update();

View File

@ -0,0 +1,219 @@
#include <signal.h>
#include "myMms_s.h"
#include "mms_s.h"
#include "mms_s_model.h"
#include "mms_s_value.h"
#include "mms_s_control.h"
#include "mms_s_param.h"
#include "mms_s_setting.h"
#include "mms_s_file.h"
#include "hal_thread.h"
LOCAL int g_running = 0;
LOCAL stru_icd *gp_icd = NULL;
LOCAL IedServer gp_iedServer = NULL;
LOCAL bool g_dbg_switch = false;
LOCAL void sigint_handler(int signum)
{
g_running = 0;
}
stru_icd *mms_s_get_icd_ptr()
{
return gp_icd;
}
IedServer mms_s_get_ied_server_ptr()
{
return gp_iedServer;
}
void mms_s_dbg_switch(bool on)
{
g_dbg_switch = on;
}
bool mms_s_dbg_get()
{
return g_dbg_switch;
}
std::string mms_s_get_string_by_mms_type(void *p_data, int type)
{
if(nullptr == p_data)
{
LOG_E("p_data is null");
return "";
}
switch(type)
{
case MMS_BOOLEAN:
return (*(uint8_t *)p_data) ? "true" : "false";
case MMS_INTEGER:
return std::to_string(*(int *)p_data);
case MMS_UNSIGNED:
return std::to_string(*(uint32_t *)p_data);
case MMS_FLOAT:
return std::to_string(*(float *)p_data);
case MMS_VISIBLE_STRING:
case MMS_STRING:
return std::string((char *)p_data);
default:
LOG_E("type %d is not supported", type);
return "";
}
}
std::string mms_s_get_string_by_type(void *p_data, int type)
{
if(nullptr == p_data)
{
LOG_E("p_data is null");
return "";
}
switch(type)
{
case DATA_TYPE_B:
return (*(uint8_t *)p_data) ? "true" : "false";
case DATA_TYPE_S8:
return std::to_string(*(int8_t *)p_data);
case DATA_TYPE_U8:
return std::to_string(*(uint8_t *)p_data);
case DATA_TYPE_S16:
return std::to_string(*(int16_t *)p_data);
case DATA_TYPE_U16:
return std::to_string(*(uint16_t *)p_data);
case DATA_TYPE_S32:
return std::to_string(*(int32_t *)p_data);
case DATA_TYPE_U32:
return std::to_string(*(uint32_t *)p_data);
case DATA_TYPE_L64:
return std::to_string(*(int64_t *)p_data);
case DATA_TYPE_UL64:
return std::to_string(*(uint64_t *)p_data);
case DATA_TYPE_F32:
return std::to_string(*(float *)p_data);
case DATA_TYPE_D64:
return std::to_string(*(double *)p_data);
case DATA_TYPE_C1:
return std::string((char *)p_data, 1);
case DATA_TYPE_C8:
return std::string((char *)p_data, 8);
case DATA_TYPE_C32:
return std::string((char *)p_data, 32);
case DATA_TYPE_C64:
return std::string((char *)p_data, 64);
case DATA_TYPE_C128:
case DATA_TYPE_STR:
return std::string((char *)p_data, 128);
default:
LOG_E("type %d is not supported", type);
return "";
}
}
LOCAL void *mms_s_run_task(void *parameter)
{
IedModel *iedModel = (IedModel *)parameter;
while(g_running)
{
IedServer_lockDataModel(gp_iedServer);
IedServer_unlockDataModel(gp_iedServer);
Thread_sleep(100);
}
IedServer_stop(gp_iedServer);
/* Cleanup - free all resources */
IedServer_destroy(gp_iedServer);
/* destroy dynamic data model */
IedModel_destroy(iedModel);
return NULL;
}
int mms_s_init(const char *icd_path, int port)
{
if(nullptr == icd_path)
{
LOG_E("icd_path is null");
return -1;
}
if(nullptr == (gp_icd = icd_parse(icd_path)))
{
LOG_E("parse icd failed");
return -1;
}
if(mms_s_dbg_get())
{
icd_show(*gp_icd);
}
if(0 != model_init(*gp_icd))
{
LOG_E("model_init failed");
return -1;
}
IedModel *iedModel = gp_icd->ied.model;
if(nullptr == iedModel)
{
LOG_E("iedModel is null");
return -1;
}
IedServerConfig serverConfig = IedServerConfig_create();
IedServerConfig_enableResvTmsForSGCB(serverConfig, true);
gp_iedServer = IedServer_createWithConfig(iedModel, NULL, serverConfig);
if(nullptr == gp_iedServer)
{
LOG_E("IedServer_createWithConfig failed");
return -1;
}
IedServer_setTimeQuality(gp_iedServer, true, false, false, 10);
IedServerConfig_destroy(serverConfig);
control_init(gp_iedServer, *gp_icd);
param_init(gp_iedServer, *gp_icd);
file_init(gp_iedServer);
IedServer_start(gp_iedServer, port);
setting_init(gp_iedServer, *gp_icd);
if(!IedServer_isRunning(gp_iedServer))
{
LOG_E("IedServer_isRunning failed");
IedServer_destroy(gp_iedServer);
gp_iedServer = NULL;
return -1;
}
g_running = 1;
signal(SIGINT, sigint_handler);
Thread mms_s_thread = Thread_create(mms_s_run_task, iedModel, false);
Thread_start(mms_s_thread);
return 0;
}

View File

@ -0,0 +1,251 @@
#include "hal_time.h"
#include "myMms_s.h"
#include "mms_s_control.h"
#include "mms_s.h"
LOCAL std::vector<stru_mms_s_control> vec_control;
LOCAL mms_s_control_cb cb_control = NULL;
LOCAL ControlHandlerResult control_handler(ControlAction action, void* parameter, MmsValue* value, bool test)
{
uint64_t timestamp = Hal_getTimeInMs();
LOG_I("control handler called");
LOG_I(" ctlNum: %i", ControlAction_getCtlNum(action));
ClientConnection clientCon = ControlAction_getClientConnection(action);
if (clientCon) {
LOG_I("Control from client %s", ClientConnection_getPeerAddress(clientCon));
}
else {
LOG_E("clientCon == NULL!");
}
IedServer server = NULL;
stru_icd *p_icd = NULL;
if(NULL == (server = mms_s_get_ied_server_ptr()))
{
LOG_E("server is NULL");
return CONTROL_RESULT_FAILED;
}
if(NULL == (p_icd = mms_s_get_icd_ptr()))
{
LOG_E("p_icd is NULL");
return CONTROL_RESULT_FAILED;
}
LOG_I("control handler called value: %s", MmsValue_getBoolean(value) ? "true" : "false");
int ret = 0;
for(std::vector<stru_contorl_DO>::iterator it = p_icd->ied.vec_control_do.begin(); it != p_icd->ied.vec_control_do.end(); ++it)
{
std::string ln_name = it->ln_prefix + it->ln_class + it->ln_inst;
if(NULL == it->p_all_do)
{
LOG_E("ld:%s, ln:%s, do:%s, control all_DO is NULL", it->ldevice_inst.c_str(), ln_name.c_str(), it->do_name.c_str());
continue;
}
if(NULL == it->p_all_do->DO)
{
LOG_E("ld:%s, ln:%s, do:%s, control DO is NULL", it->ldevice_inst.c_str(), ln_name.c_str(), it->do_name.c_str());
continue;
}
if(NULL == it->p_all_do)
{
LOG_E("ld:%s, ln:%s, do:%s, control all_DO is NULL", it->ldevice_inst.c_str(), ln_name.c_str(), it->do_name.c_str());
continue;
}
ret = 0;
if(it->p_all_do->DO == parameter)
{
if(it->p_all_do->map_all_da.find("t") != it->p_all_do->map_all_da.end() && it->p_all_do->map_all_da.find("stVal") != it->p_all_do->map_all_da.end())
{
ret = 1;
IedServer_updateUTCTimeAttributeValue(server, it->p_all_do->map_all_da["t"]->DA, timestamp);
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<stru_mms_s_control>::iterator it_control = vec_control.begin(); it_control != vec_control.end(); ++it_control)
{
if(it_control->saddr == saddr)
{
if(NULL != cb_control)
{
cb_control(&*it_control, MmsValue_getBoolean(value) ? 1 : 0);
}
}
}
if(stVal->type == IEC61850_BOOLEAN)
{
IedServer_updateAttributeValue(server, stVal, value);
}
else if(stVal->type == IEC61850_GENERIC_BITSTRING)
{
Dbpos pos = MmsValue_getBoolean(value) == true ? DBPOS_ON : DBPOS_OFF;
IedServer_updateDbposValue(server, stVal, pos);
LOG_I("da %s-%s, pos %d", stVal->parent->name, stVal->name, pos);
}
else
{
ret = 0;
}
}
if(ret == 1)
{
LOG_I("ld:%s, ln:%s, do:%s, control success", it->ldevice_inst.c_str(), ln_name.c_str(), it->do_name.c_str());
}
else
{
LOG_E("ld:%s, ln:%s, do:%s, control failed", it->ldevice_inst.c_str(), ln_name.c_str(), it->do_name.c_str());
}
break;
}
}
return ret == 1 ? CONTROL_RESULT_OK : CONTROL_RESULT_FAILED;
}
LOCAL CheckHandlerResult check_handler(ControlAction action, void* parameter, MmsValue* ctlVal, bool test, bool interlockCheck)
{
ClientConnection clientCon = ControlAction_getClientConnection(action);
if (clientCon) {
LOG_I("Control from client %s\n", ClientConnection_getPeerAddress(clientCon));
}
else {
LOG_E("clientCon == NULL\n");
}
if (ControlAction_isSelect(action))
LOG_I("check handler called by select command!\n");
else
LOG_I("check handler called by operate command!\n");
if (interlockCheck)
LOG_I(" with interlock check bit set!\n");
LOG_I(" ctlNum: %i\n", ControlAction_getCtlNum(action));
IedServer server = NULL;
stru_icd *p_icd = NULL;
if(NULL == (server = mms_s_get_ied_server_ptr()))
{
LOG_E("server is NULL");
return CONTROL_HARDWARE_FAULT;
}
if(NULL == (p_icd = mms_s_get_icd_ptr()))
{
LOG_E("p_icd is NULL");
return CONTROL_HARDWARE_FAULT;
}
for(std::vector<stru_contorl_DO>::iterator it = p_icd->ied.vec_control_do.begin(); it != p_icd->ied.vec_control_do.end(); ++it)
{
std::string ln_name = it->ln_prefix + it->ln_class + it->ln_inst;
if(NULL == it->p_all_do)
{
LOG_E("ld:%s, ln:%s, do:%s, control all_DO is NULL", it->ldevice_inst.c_str(), ln_name.c_str(), it->do_name.c_str());
continue;
}
if(NULL == it->p_all_do->DO)
{
LOG_E("ld:%s, ln:%s, do:%s, control DO is NULL", it->ldevice_inst.c_str(), ln_name.c_str(), it->do_name.c_str());
continue;
}
if(it->p_all_do->DO == parameter)
{
LOG_I("return CONTROL_ACCEPTED");
return CONTROL_ACCEPTED;
}
}
LOG_E("return CONTROL_OBJECT_UNDEFINED");
return CONTROL_OBJECT_UNDEFINED;
}
int mms_s_control_register(stru_mms_s_control *p_control, uint16_t num, mms_s_control_cb cb)
{
if(NULL == p_control || num == 0)
{
LOG_E("p_control is NULL or num is 0");
return -1;
}
vec_control.clear();
vec_control.reserve(num);
for(uint16_t i = 0; i < num; ++i)
{
vec_control.push_back(p_control[i]);
}
if(NULL != cb)
{
cb_control = cb;
}
return 0;
}
int control_init(IedServer server, stru_icd &icd)
{
if(NULL == server)
{
LOG_E("server is NULL");
return -1;
}
if(vec_control.empty())
{
LOG_E("vec_control is empty");
return 0;
}
for(std::vector<stru_contorl_DO>::iterator it = icd.ied.vec_control_do.begin(); it != icd.ied.vec_control_do.end(); ++it)
{
std::string ln_name = it->ln_prefix + it->ln_class + it->ln_inst;
if(NULL == it->p_all_do)
{
LOG_E("ld:%s, ln:%s, do:%s, control all_DO is NULL", it->ldevice_inst.c_str(), ln_name.c_str(), it->do_name.c_str());
continue;
}
if(NULL == it->p_all_do->DO)
{
LOG_E("ld:%s, ln:%s, do:%s, control DO is NULL", it->ldevice_inst.c_str(), ln_name.c_str(), it->do_name.c_str());
continue;
}
IedServer_setControlHandler(server, it->p_all_do->DO, (ControlHandler)control_handler, it->p_all_do->DO);
IedServer_setPerformCheckHandler(server, it->p_all_do->DO, check_handler, it->p_all_do->DO);
}
return 0;
}

View File

@ -0,0 +1,70 @@
#include "mms_s_file.h"
LOCAL std::string g_file_path = "";
LOCAL void connectionHandler (IedServer self, ClientConnection connection, bool connected, void* parameter)
{
if (connected)
LOG_I("Connection opened\n");
else
LOG_I("Connection closed\n");
}
LOCAL MmsError fileAccessHandler (void* parameter, MmsServerConnection connection, MmsFileServiceType service, const char* localFilename, const char* otherFilename)
{
LOG_I("fileAccessHandler: service = %i, local-file: %s other-file: %s\n", service, localFilename, otherFilename);
/* Don't allow client to rename files */
if (service == MMS_FILE_ACCESS_TYPE_RENAME)
return MMS_ERROR_FILE_FILE_ACCESS_DENIED;
/* Don't allow client to delete file "IEDSERVER.BIN" */
if (service == MMS_FILE_ACCESS_TYPE_DELETE)
{
if (strcmp(localFilename, "IEDSERVER.BIN") == 0)
return MMS_ERROR_FILE_FILE_ACCESS_DENIED;
}
/* allow all other accesses */
return MMS_ERROR_NONE;
}
int mms_s_file_path_set(const char* file_path)
{
if(nullptr == file_path)
{
LOG_I("file_path is NULL");
return 0;
}
g_file_path = file_path;
LOG_I("file_path = %s", g_file_path.c_str());
return 0;
}
int file_init(IedServer server)
{
if(g_file_path.empty())
{
LOG_I("file_path is empty");
return 0;
}
MmsServer mmsServer = IedServer_getMmsServer(server);
if(nullptr == mmsServer)
{
LOG_E("mmsServer is NULL");
return -1;
}
IedServer_setFilestoreBasepath(server, g_file_path.c_str());
MmsServer_installFileAccessHandler(mmsServer, fileAccessHandler, NULL);
IedServer_setConnectionIndicationHandler(server, (IedConnectionIndicationHandler) connectionHandler, NULL);
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,624 @@
#include <math.h>
#include "myMms_s.h"
#include "mms_s_param.h"
// #include "cJSON.h"
LOCAL std::vector<stru_mms_s_param> vec_params;
LOCAL mms_s_param_cb g_param_cb = NULL;
void param_update_BOOLEAN(IedServer server, DataAttribute* dataAttribute, std::string val)
{
if(NULL == server || NULL == dataAttribute)
{
LOG_E("server or dataAttribute is NULL");
return;
}
IedServer_updateBooleanAttributeValue(server, dataAttribute, val == "1" ? true : false); // call
}
void param_update_INT(IedServer server, DataAttribute* dataAttribute, std::string val)
{
if(NULL == server || NULL == dataAttribute)
{
LOG_E("server or dataAttribute is NULL");
return;
}
IedServer_updateInt32AttributeValue(server, dataAttribute, atoi(val.c_str()));
}
void param_update_UINT(IedServer server, DataAttribute* dataAttribute, std::string val)
{
if(NULL == server || NULL == dataAttribute)
{
LOG_E("server or dataAttribute is NULL");
return;
}
IedServer_updateUnsignedAttributeValue(server, dataAttribute, atoi(val.c_str()));
}
void param_update_FLOAT(IedServer server, DataAttribute* dataAttribute, std::string val)
{
if(NULL == server || NULL == dataAttribute)
{
LOG_E("server or dataAttribute is NULL");
return;
}
IedServer_updateFloatAttributeValue(server, dataAttribute, atof(val.c_str()));
}
void param_update_VISIBLE_STRING(IedServer server, DataAttribute* dataAttribute, std::string val)
{
if(NULL == server || NULL == dataAttribute)
{
LOG_E("server or dataAttribute is NULL");
return;
}
IedServer_updateVisibleStringAttributeValue(server, dataAttribute, (char *)val.c_str());
}
void param_update_STRING(IedServer server, DataAttribute* dataAttribute, std::string val)
{
if(NULL == server || NULL == dataAttribute)
{
LOG_E("server or dataAttribute is NULL");
return;
}
IedServer_updateAttributeValue(server, dataAttribute, MmsValue_newMmsString((char *)val.c_str()));
}
LOCAL struct
{
MmsType type;
void (*update_value)(IedServer server, DataAttribute* dataAttribute, std::string val);
}g_param_update_funcs[] =
{
{MMS_BOOLEAN, param_update_BOOLEAN},
{MMS_INTEGER, param_update_INT},
{MMS_UNSIGNED, param_update_UINT},
{MMS_FLOAT, param_update_FLOAT},
{MMS_VISIBLE_STRING, param_update_VISIBLE_STRING},
{MMS_STRING, param_update_STRING},
};
LOCAL int g_param_update_funcs_count = sizeof(g_param_update_funcs)/sizeof(g_param_update_funcs[0]);
LOCAL void param_load_active_sg_values(stru_LDevice &ld, int actSG)
{
stru_icd *p_icd = mms_s_get_icd_ptr();
if(NULL == p_icd)
{
LOG_E("p_icd is NULL");
return;
}
for(std::vector<stru_mms_s_param>::iterator it_param = vec_params.begin(); it_param != vec_params.end(); it_param++)
{
std::string saddr = std::string(it_param->base.saddr) + "_SG";
if(it_param->param_num < 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);
if(p_icd->ied.map_saddr_point.find(saddr) == p_icd->ied.map_saddr_point.end())
{
LOG_E("sAddr %s not found in ICD", saddr.c_str());
continue;
}
ModelNode *node = p_icd->ied.map_saddr_point[saddr].node;
if(node == NULL)
{
LOG_E("ModelNode for sAddr %s is NULL", saddr.c_str());
continue;
}
int match = 0;
for(int i = 0; i < g_param_update_funcs_count; i++)
{
if(MmsValue_getType(((DataAttribute *)node)->mmsValue) == g_param_update_funcs[i].type)
{
g_param_update_funcs[i].update_value(mms_s_get_ied_server_ptr(), (DataAttribute *)node, val);
match = 1;
break;
}
}
if(!match)
{
LOG_E("No update function found for sAddr %s with MMS type %d", saddr.c_str(), MmsValue_getType(((DataAttribute *)node)->mmsValue));
continue;
}
}
LOG_I("Load active setting group %d values done", actSG);
}
LOCAL void param_load_edit_sg_values(stru_LDevice &ld, int editSG)
{
stru_icd *p_icd = mms_s_get_icd_ptr();
if(NULL == p_icd)
{
LOG_E("p_icd is NULL");
return;
}
for(std::vector<stru_mms_s_param>::iterator it_param = vec_params.begin(); it_param != vec_params.end(); it_param++)
{
std::string saddr = std::string(it_param->base.saddr) + "_SE";
if(it_param->param_num < 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);
if(p_icd->ied.map_saddr_point.find(saddr) == p_icd->ied.map_saddr_point.end())
{
LOG_E("sAddr %s not found in ICD", saddr.c_str());
continue;
}
ModelNode *node = p_icd->ied.map_saddr_point[saddr].node;
if(node == NULL)
{
LOG_E("ModelNode for sAddr %s is NULL", saddr.c_str());
continue;
}
int match = 0;
for(int i = 0; i < g_param_update_funcs_count; i++)
{
if(MmsValue_getType(((DataAttribute *)node)->mmsValue) == g_param_update_funcs[i].type)
{
g_param_update_funcs[i].update_value(mms_s_get_ied_server_ptr(), (DataAttribute *)node, val);
match = 1;
break;
}
}
if(!match)
{
LOG_E("No update function found for sAddr %s with MMS type %d", saddr.c_str(), MmsValue_getType(((DataAttribute *)node)->mmsValue));
continue;
}
}
}
LOCAL bool param_active_sg_changed_handler(void* parameter, SettingGroupControlBlock* sgcb, uint8_t newActSg, ClientConnection connection)
{
if(NULL == parameter || NULL == sgcb)
{
LOG_E("parameter %p or sgcb %p is NULL", parameter, sgcb);
return false;
}
stru_LDevice *p_ld = (stru_LDevice*)parameter;
LOG_I("Switch to setting group %i\n", (int) newActSg);
param_load_active_sg_values(*p_ld, newActSg);
return true;
}
LOCAL bool param_edit_sg_changed_handler(void* parameter, SettingGroupControlBlock* sgcb, uint8_t newEditSg, ClientConnection connection)
{
if(NULL == parameter || NULL == sgcb)
{
LOG_E("parameter %p or sgcb %p is NULL", parameter, sgcb);
return false;
}
stru_LDevice *p_ld = (stru_LDevice*)parameter;
LOG_I("Set edit setting group to %i\n", (int) newEditSg);
param_load_edit_sg_values(*p_ld, newEditSg);
return true;
}
LOCAL void param_min_max_step_get(DataAttribute *node, float &min, float &max, float &step)
{
if(node == NULL)
{
LOG_E("node is NULL");
return;
}
if(node->parent == NULL)
{
LOG_E("DataAttribute has no parent");
return;
}
MmsType type = MmsValue_getType(node->mmsValue);
if(type == MMS_STRING || type == MMS_BOOLEAN )
{
// For string type, min, max and step are not applicable
min = 0;
max = 0;
step = 0;
return;
}
DataAttribute *da_node = (DataAttribute *)node->parent;
DataAttribute *da_first = (DataAttribute *)da_node->firstChild;
while(da_first != NULL)
{
if(strcmp(da_first->name, "minVal") == 0)
{
if(type == MMS_FLOAT)
{
min = MmsValue_toFloat(da_first->mmsValue);
}
else
{
min = (float)MmsValue_toInt32(da_first->mmsValue);
}
}
else if(strcmp(da_first->name, "maxVal") == 0)
{
if(type == MMS_FLOAT)
{
max = MmsValue_toFloat(da_first->mmsValue);
}
else
{
max = (float)MmsValue_toInt32(da_first->mmsValue);
}
}
else if(strcmp(da_first->name, "stepSize") == 0)
{
if(type == MMS_FLOAT)
{
step = MmsValue_toFloat(da_first->mmsValue);
}
else
{
step = (float)MmsValue_toInt32(da_first->mmsValue);
}
}
da_first = (DataAttribute *)da_first->sibling;
}
}
LOCAL void param_get_BOOLEAN(DataAttribute *node, std::string &val)
{
if(node == NULL)
{
LOG_E("node is NULL");
return;
}
val = MmsValue_getBoolean(node->mmsValue) ? "1" : "0";
}
LOCAL void param_get_INT(DataAttribute *node, std::string &val)
{
if(node == NULL)
{
LOG_E("node is NULL");
return;
}
float min, max, step;
param_min_max_step_get(node, min, max, step);
if((int)step == 0)
{
return;
}
int intVal = MmsValue_toInt32(node->mmsValue);
if(intVal < (int)min || intVal > (int)max)
{
LOG_E("Value %d is out of range [%d, %d]", intVal, (int)min, (int)max);
return;
}
int gap = intVal - (int)min;
if(gap != 0 && gap % (int)step != 0)
{
LOG_E("Value %d does not conform to step size %d", intVal, (int)step);
return;
}
val = std::to_string(intVal);
}
LOCAL void param_get_UINT(DataAttribute *node, std::string &val)
{
if(node == NULL)
{
LOG_E("node is NULL");
return;
}
float min, max, step;
param_min_max_step_get(node, min, max, step);
if((uint32_t)step == 0)
{
return;
}
int uintVal = MmsValue_toUint32(node->mmsValue);
if(uintVal < (uint32_t)min || uintVal > (uint32_t)max)
{
LOG_E("Value %d is out of range [%d, %d]", uintVal, (uint32_t)min, (uint32_t)max);
return;
}
int gap = uintVal - (uint32_t)min;
if(gap != 0 && gap % (uint32_t)step != 0)
{
LOG_E("Value %d does not conform to step size %d", uintVal, (uint32_t)step);
return;
}
val = std::to_string(uintVal);
}
LOCAL void param_get_FLOAT(DataAttribute *node, std::string &val)
{
if(node == NULL)
{
LOG_E("node is NULL");
return;
}
float min, max, step;
param_min_max_step_get(node, min, max, step);
const float EPSILON = 1e-6;
float floatVal = MmsValue_toFloat(node->mmsValue);
if(floatVal < min - EPSILON || floatVal > max + EPSILON)
{
LOG_E("Value %f is out of range [%f, %f]", floatVal, min, max);
return;
}
if(fabs(step) < EPSILON)
{
val = std::to_string(floatVal);
return;
}
float gap = floatVal - min;
float gap_mod = fmod(gap, step);
if(fabs(gap_mod) > EPSILON && fabs(gap_mod - step) > EPSILON)
{
LOG_E("Value %f does not conform to step size %f", floatVal, step);
return;
}
val = std::to_string(floatVal);
}
LOCAL void param_get_STRING(DataAttribute *node, std::string &val)
{
if(node == NULL)
{
LOG_E("node is NULL");
return;
}
val = MmsValue_toString(node->mmsValue);
}
LOCAL struct
{
MmsType type;
void (*get_value)(DataAttribute *node, std::string &val);
}g_param_get_funcs[] =
{
{MMS_BOOLEAN, param_get_BOOLEAN},
{MMS_INTEGER, param_get_INT},
{MMS_UNSIGNED, param_get_UINT},
{MMS_FLOAT, param_get_FLOAT},
{MMS_VISIBLE_STRING, param_get_STRING},
{MMS_STRING, param_get_STRING},
};
LOCAL int g_param_get_funcs_count = sizeof(g_param_get_funcs)/sizeof(g_param_get_funcs[0]);
LOCAL void edit_sg_confirmation_handler(void* parameter, SettingGroupControlBlock* sgcb, uint8_t editSg)
{
if(NULL == parameter || NULL == sgcb)
{
LOG_E("parameter %p or sgcb %p is NULL", parameter, sgcb);
return;
}
stru_LDevice *p_ld = (stru_LDevice*)parameter;
LOG_I("Received edit sg confirm for sg %i\n", editSg);
IedServer server = mms_s_get_ied_server_ptr();
if(NULL == server)
{
LOG_E("server is NULL");
return;
}
stru_icd *p_icd = mms_s_get_icd_ptr();
if(NULL == p_icd)
{
LOG_E("p_icd is NULL");
return;
}
for(std::vector<stru_mms_s_param>::iterator it_param = vec_params.begin(); it_param != vec_params.end(); it_param++)
{
std::string saddr = std::string(it_param->base.saddr) + "_SE";
if(it_param->param_num < 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);
if(p_icd->ied.map_saddr_point.find(saddr) == p_icd->ied.map_saddr_point.end())
{
LOG_E("sAddr %s not found in ICD", saddr.c_str());
continue;
}
ModelNode *node = p_icd->ied.map_saddr_point[saddr].node;
if(node == NULL)
{
LOG_E("ModelNode for sAddr %s is NULL", saddr.c_str());
continue;
}
int match = 0;
for(int i = 0; i < g_param_get_funcs_count; i++)
{
if(MmsValue_getType(((DataAttribute *)node)->mmsValue) == g_param_get_funcs[i].type)
{
g_param_get_funcs[i].get_value((DataAttribute *)node, val);
match = 1;
break;
}
}
if(!match)
{
LOG_E("No get function found for sAddr %s with MMS type %d", saddr.c_str(), MmsValue_getType(((DataAttribute *)node)->mmsValue));
continue;
}
}
if(IedServer_getActiveSettingGroup(server, sgcb) == editSg)
{
param_load_active_sg_values(*p_ld, editSg);
}
}
LOCAL MmsDataAccessError read_access_handler(LogicalDevice* ld, LogicalNode* ln, DataObject* dataObject, FunctionalConstraint fc, ClientConnection connection, void* parameter)
{
// if(NULL == ld || NULL == ln || NULL == connection || NULL == parameter)
// {
// LOG_E("parameter %p or ld %p or ln %p or connection %p is NULL", parameter, ld, ln, connection);
// return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
// }
// stru_LDevice *p_ld = (stru_LDevice*)parameter;
// void* securityToken = ClientConnection_getSecurityToken(connection);
// if (dataObject)
// printf("Read access to %s/%s.%s[%s]\n", ld->name, ln->name, dataObject->name, FunctionalConstraint_toString(fc));
// else
// printf("Read access to %s/%s[%s]\n", ld->name, ln->name, FunctionalConstraint_toString(fc));
return DATA_ACCESS_ERROR_SUCCESS;
}
LOCAL void param_values_show()
{
if(vec_params.empty())
{
LOG_E("vec_params is empty");
return;
}
for(uint16_t i = 0; i < vec_params.size(); i++)
{
stru_mms_s_param &param = 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);
printf("index %d, val %s\n", j, val.c_str());
}
printf("\n");
}
}
int mms_s_param_register(stru_mms_s_param *p_param, uint16_t num, mms_s_param_cb cb)
{
if(nullptr == p_param || num == 0)
{
LOG_E("p_param is NULL or num is 0");
return -1;
}
vec_params.clear();
vec_params.reserve(num);
for(uint16_t i = 0; i < num; i++)
{
vec_params.push_back(p_param[i]);
}
if(NULL != cb)
{
g_param_cb = cb;
}
return 0;
}
int param_init(IedServer server, stru_icd &icd)
{
if(vec_params.empty())
{
LOG_E("vec_params is empty");
return 0;
}
param_values_show();
for(std::map<std::string, stru_LDevice>::iterator it_ld = icd.ied.map_ldevice.begin(); it_ld!= icd.ied.map_ldevice.end(); it_ld++)
{
stru_LDevice *p_ld = &it_ld->second;
if(NULL == p_ld->sgcb)
{
LOG_E("sgcb of %s is NULL", it_ld->first.c_str());
continue;
}
LogicalNode *ln0 = p_ld->sgcb->parent;
LOG_I("ld %s sgcb ln0 %s, actSG %d, numofSGs %d, editSG %d, cnfEdit %d, timestamp %ld, resvTms %d, sibling %p",
it_ld->first.c_str(), ln0 ? ln0->name : "NULL", p_ld->sgcb->actSG, p_ld->sgcb->numOfSGs, p_ld->sgcb->editSG,
p_ld->sgcb->cnfEdit, p_ld->sgcb->timestamp, p_ld->sgcb->resvTms, p_ld->sgcb->sibling);
param_load_active_sg_values(*p_ld, p_ld->sgcb->actSG);
IedServer_setActiveSettingGroupChangedHandler(server, p_ld->sgcb, param_active_sg_changed_handler, p_ld);
IedServer_setEditSettingGroupChangedHandler(server, p_ld->sgcb, param_edit_sg_changed_handler, p_ld);
IedServer_setEditSettingGroupConfirmationHandler(server, p_ld->sgcb, edit_sg_confirmation_handler, p_ld);
IedServer_setReadAccessHandler(server, read_access_handler, p_ld);
}
return 0;
}

View File

@ -0,0 +1,523 @@
#include <math.h>
#include "myMms_s.h"
#include "mms_s_setting.h"
// #include "cJSON.h"
LOCAL std::vector<stru_mms_s_setting> vec_settings;
LOCAL mms_s_setting_cb cb_setting = NULL;
void setting_update_BOOLEAN(IedServer server, DataAttribute* dataAttribute, std::string val)
{
if(NULL == server || NULL == dataAttribute)
{
LOG_E("server or dataAttribute is NULL");
return;
}
IedServer_updateBooleanAttributeValue(server, dataAttribute, val == "1" ? true : false); // call
}
void setting_update_INT(IedServer server, DataAttribute* dataAttribute, std::string val)
{
if(NULL == server || NULL == dataAttribute)
{
LOG_E("server or dataAttribute is NULL");
return;
}
IedServer_updateInt32AttributeValue(server, dataAttribute, atoi(val.c_str()));
}
void setting_update_UINT(IedServer server, DataAttribute* dataAttribute, std::string val)
{
if(NULL == server || NULL == dataAttribute)
{
LOG_E("server or dataAttribute is NULL");
return;
}
IedServer_updateUnsignedAttributeValue(server, dataAttribute, atoi(val.c_str()));
}
void setting_update_FLOAT(IedServer server, DataAttribute* dataAttribute, std::string val)
{
if(NULL == server || NULL == dataAttribute)
{
LOG_E("server or dataAttribute is NULL");
return;
}
IedServer_updateFloatAttributeValue(server, dataAttribute, atof(val.c_str()));
}
void setting_update_VISIBLE_STRING(IedServer server, DataAttribute* dataAttribute, std::string val)
{
if(NULL == server || NULL == dataAttribute)
{
LOG_E("server or dataAttribute is NULL");
return;
}
IedServer_updateVisibleStringAttributeValue(server, dataAttribute, (char *)val.c_str());
}
void setting_update_STRING(IedServer server, DataAttribute* dataAttribute, std::string val)
{
if(NULL == server || NULL == dataAttribute)
{
LOG_E("server or dataAttribute is NULL");
return;
}
IedServer_updateAttributeValue(server, dataAttribute, MmsValue_newMmsString((char *)val.c_str()));
}
LOCAL struct
{
MmsType type;
void (*update_value)(IedServer server, DataAttribute* dataAttribute, std::string val);
}g_setting_update_funcs[] =
{
{MMS_BOOLEAN, setting_update_BOOLEAN},
{MMS_INTEGER, setting_update_INT},
{MMS_UNSIGNED, setting_update_UINT},
{MMS_FLOAT, setting_update_FLOAT},
{MMS_VISIBLE_STRING, setting_update_VISIBLE_STRING},
{MMS_STRING, setting_update_STRING},
};
LOCAL int g_setting_update_funcs_count = sizeof(g_setting_update_funcs)/sizeof(g_setting_update_funcs[0]);
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++)
{
std::string sAddr = it->base.saddr;
std::string str = mms_s_get_string_by_type(it->data, it->base.type);
if(icd.ied.map_saddr_point.find(sAddr) == icd.ied.map_saddr_point.end())
{
LOG_E("sAddr %s not found in ICD", sAddr.c_str());
continue;
}
ModelNode *node = icd.ied.map_saddr_point[sAddr].node;
if(node == NULL)
{
LOG_E("ModelNode for sAddr %s is NULL", sAddr.c_str());
continue;
}
if(((DataAttribute *)node)->fc != IEC61850_FC_SP)
{
LOG_E("sAddr %s is not SP", sAddr.c_str());
continue;
}
int match = 0;
for(int i = 0; i < g_setting_update_funcs_count; i++)
{
if(MmsValue_getType(((DataAttribute *)node)->mmsValue) == g_setting_update_funcs[i].type)
{
g_setting_update_funcs[i].update_value(server, (DataAttribute *)node, str);
match = 1;
break;
}
}
if(!match)
{
LOG_E("No update function found for sAddr %s with MMS type %d", sAddr.c_str(), MmsValue_getType(((DataAttribute *)node)->mmsValue));
}
}
}
LOCAL void setting_min_max_step_get(DataAttribute *node, float &min, float &max, float &step)
{
if(node == NULL)
{
LOG_E("node is NULL");
return;
}
if(node->parent == NULL)
{
LOG_E("DataAttribute has no parent");
return;
}
MmsType type = MmsValue_getType(node->mmsValue);
if(type == MMS_STRING || type == MMS_BOOLEAN)
{
// For string type, min, max and step are not applicable
min = 0;
max = 0;
step = 0;
return;
}
DataAttribute *da_node = (DataAttribute *)node->parent;
DataAttribute *da_first = (DataAttribute *)da_node->firstChild;
while(da_first != NULL)
{
if(strcmp(da_first->name, "minVal") == 0)
{
if(type == MMS_FLOAT)
{
min = MmsValue_toFloat(da_first->mmsValue);
}
else
{
min = (float)MmsValue_toInt32(da_first->mmsValue);
}
}
else if(strcmp(da_first->name, "maxVal") == 0)
{
if(type == MMS_FLOAT)
{
max = MmsValue_toFloat(da_first->mmsValue);
}
else
{
max = (float)MmsValue_toInt32(da_first->mmsValue);
}
}
else if(strcmp(da_first->name, "stepSize") == 0)
{
if(type == MMS_FLOAT)
{
step = MmsValue_toFloat(da_first->mmsValue);
}
else
{
step = (float)MmsValue_toInt32(da_first->mmsValue);
}
}
da_first = (DataAttribute *)da_first->sibling;
}
}
LOCAL int setting_get_BOOLEAN(DataAttribute *node, MmsValue* value, std::string &val_str)
{
if(node == NULL || value == NULL)
{
LOG_E("node or value is NULL");
return -1;
}
bool val = MmsValue_getBoolean(value);
if(val != true && val != false)
{
LOG_E("Invalid boolean value for node %s", node->name);
return -1;
}
LOG_I("Boolean value for node %s is %d", node->name, val);
val_str = val ? "true" : "false";
return 0;
}
LOCAL int setting_get_INT(DataAttribute *node, MmsValue* value, std::string &val_str)
{
if(node == NULL || value == NULL)
{
LOG_E("node or value is NULL");
return -1;
}
float min, max, step;
setting_min_max_step_get(node, min, max, step);
if((int)step == 0)
{
return -1;
}
int intVal = MmsValue_toInt32(value);
if(intVal < (int)min || intVal > (int)max)
{
LOG_E("Value %d is out of range [%d, %d]", intVal, (int)min, (int)max);
return -1;
}
int gap = intVal - (int)min;
if(gap != 0 && gap % (int)step != 0)
{
LOG_E("Value %d does not conform to step size %d", intVal, (int)step);
return -1;
}
LOG_I("Integer value for node %s is %d", node->name, intVal);
val_str = std::to_string(intVal);
return 0;
}
LOCAL int setting_get_UINT(DataAttribute *node, MmsValue* value, std::string &val_str)
{
if(node == NULL || value == NULL)
{
LOG_E("node or value is NULL");
return -1;
}
float min, max, step;
setting_min_max_step_get(node, min, max, step);
if((uint32_t)step == 0)
{
return -1;
}
int uintVal = MmsValue_toUint32(value);
if(uintVal < (uint32_t)min || uintVal > (uint32_t)max)
{
LOG_E("Value %d is out of range [%d, %d]", uintVal, (uint32_t)min, (uint32_t)max);
return -1;
}
int gap = uintVal - (uint32_t)min;
if(gap != 0 && gap % (uint32_t)step != 0)
{
LOG_E("Value %d does not conform to step size %d", uintVal, (uint32_t)step);
return -1;
}
LOG_I("Unsigned integer value for node %s is %d", node->name, uintVal);
val_str = std::to_string(uintVal);
return 0;
}
LOCAL int setting_get_FLOAT(DataAttribute *node, MmsValue* value, std::string &val_str)
{
if(node == NULL || value == NULL)
{
LOG_E("node or value is NULL");
return -1;
}
float min, max, step;
setting_min_max_step_get(node, min, max, step);
const float EPSILON = 1e-6;
float floatVal = MmsValue_toFloat(value);
if(floatVal < min - EPSILON || floatVal > max + EPSILON)
{
LOG_E("Value %f is out of range [%f, %f]", floatVal, min, max);
return -1;
}
if(fabs(step) < EPSILON)
{
return 0;
}
float gap = floatVal - min;
float gap_mod = fmod(gap, step);
if(fabs(gap_mod) > EPSILON && fabs(gap_mod - step) > EPSILON)
{
LOG_E("Value %f does not conform to step size %f", floatVal, step);
return -1;
}
LOG_I("Float value for node %s is %f", node->name, floatVal);
val_str = std::to_string(floatVal);
return 0;
}
LOCAL int setting_get_STRING(DataAttribute *node, MmsValue* value, std::string &val_str)
{
if(node == NULL || value == NULL)
{
LOG_E("node or value is NULL");
return -1;
}
LOG_I("String value for node %s is %s", node->name, MmsValue_toString(value));
val_str = MmsValue_toString(value);
return 0;
}
LOCAL struct
{
MmsType type;
int (*get_value)(DataAttribute *node, MmsValue* value, std::string &val_str);
}g_setting_get_funcs[] =
{
{MMS_BOOLEAN, setting_get_BOOLEAN},
{MMS_INTEGER, setting_get_INT},
{MMS_UNSIGNED, setting_get_UINT},
{MMS_FLOAT, setting_get_FLOAT},
{MMS_VISIBLE_STRING, setting_get_STRING},
{MMS_STRING, setting_get_STRING},
};
LOCAL int g_setting_get_funcs_count = sizeof(g_setting_get_funcs)/sizeof(g_setting_get_funcs[0]);
LOCAL MmsDataAccessError writeAccessHandler (DataAttribute* dataAttribute, MmsValue* value, ClientConnection connection, void* parameter)
{
stru_icd *p_icd = mms_s_get_icd_ptr();
if(NULL == p_icd)
{
LOG_E("p_icd is NULL");
return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
}
LOG_I("da %p, value %p, connection %p, parameter %p", dataAttribute, value, connection, parameter);
if(dataAttribute)
{
LOG_I("da name: %s, sAddr: %s, fc %d", dataAttribute->name, dataAttribute->sAddr, dataAttribute->fc);
}
// for(int i = 0; i < vec_settings.size(); i++)
for(std::vector<stru_mms_s_setting>::iterator it = vec_settings.begin(); it != vec_settings.end(); it++)
{
std::string sAddr = it->base.saddr;
if(p_icd->ied.map_saddr_point.find(sAddr) == p_icd->ied.map_saddr_point.end())
{
LOG_E("sAddr %s not found in ICD", sAddr.c_str());
continue;
}
ModelNode *node = p_icd->ied.map_saddr_point[sAddr].node;
if(node == NULL)
{
LOG_E("ModelNode for sAddr %s is NULL", sAddr.c_str());
continue;
}
if(node != (ModelNode *)dataAttribute)
{
continue;
}
for(int i = 0; i < g_setting_get_funcs_count; i++)
{
if(MmsValue_getType(dataAttribute->mmsValue) == g_setting_get_funcs[i].type)
{
std::string val_str = "";
int ret = g_setting_get_funcs[i].get_value(dataAttribute, value, val_str);
if(ret == 0)
{
if(cb_setting != NULL)
{
LOG_I("cb_setting %p, sAddr %s, val %s", cb_setting, sAddr.c_str(), val_str.c_str());
cb_setting(&*it, val_str.c_str());
}
return DATA_ACCESS_ERROR_SUCCESS;
}
break;
}
}
}
LOG_E("No update function found for sAddr %s with MMS type %d", dataAttribute->sAddr, MmsValue_getType(dataAttribute->mmsValue));
return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
}
LOCAL void setting_handle_init(IedServer server, stru_icd &icd)
{
for(int i = 0; i < vec_settings.size(); i++)
{
std::string sAddr = vec_settings[i].base.saddr;
if(icd.ied.map_saddr_point.find(sAddr) == icd.ied.map_saddr_point.end())
{
LOG_E("sAddr %s not found in ICD", sAddr.c_str());
continue;
}
ModelNode *node = icd.ied.map_saddr_point[sAddr].node;
if(node == NULL)
{
LOG_E("ModelNode for sAddr %s is NULL", sAddr.c_str());
continue;
}
if(node->modelType != DataAttributeModelType)
{
LOG_E("ModelNode for sAddr %s is not DataAttributeModelType", sAddr.c_str());
continue;
}
if(((DataAttribute *)node)->fc != IEC61850_FC_SP)
{
LOG_E("sAddr %s is not SP", sAddr.c_str());
continue;
}
IedServer_handleWriteAccess(server, (DataAttribute *)node, writeAccessHandler, NULL);
DataAttribute *da = (DataAttribute *)node;
LOG_I("Write access handler set for sAddr %s, data attribute name: %s, da %p", sAddr.c_str(), da->name, da);
}
}
LOCAL void setting_values_show()
{
for(int i = 0; i < vec_settings.size(); i++)
{
stru_mms_s_setting &setting = vec_settings[i];
LOG_I("saddr %s, desc %s, type %d",
setting.base.saddr, setting.base.desc, setting.base.type);
}
}
int mms_s_setting_register(stru_mms_s_setting *p_setting, uint16_t num, mms_s_setting_cb cb)
{
if(p_setting == NULL || num == 0)
{
LOG_E("p_setting or num is NULL or 0");
return -1;
}
vec_settings.clear();
vec_settings.reserve(num);
for(int i = 0; i < num; i++)
{
vec_settings.push_back(p_setting[i]);
}
if(cb != NULL)
{
cb_setting = cb;
}
return 0;
}
int setting_init(IedServer server, stru_icd &icd)
{
if(vec_settings.empty())
{
LOG_E("vec_settings is empty");
return 0;
}
setting_values_show();
setting_value_init(server, icd);
/* Don't allow access to SP variables by default */
IedServer_setWriteAccessPolicy(server, IEC61850_FC_SP, ACCESS_POLICY_DENY);
setting_handle_init(server, icd);
return 0;
}

View File

@ -0,0 +1,767 @@
#include "mms_s_value.h"
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 struct
{
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},
};
LOCAL int g_iec61850s_value_update_cb_count = sizeof(g_iec61850s_value_update_cb) / sizeof(g_iec61850s_value_update_cb[0]);
LOCAL void model_da_value_update_Boolean(IedServer server, DataAttribute *da, void *value)
{
if(NULL == server || NULL == da || NULL == value || strlen((char*)value) == 0)
{
// LOG_E("server, da or value is NULL");
return;
}
int int_value = atoi((char*)value);
if(int_value == 0)
{
IedServer_updateBooleanAttributeValue(server, da, false);
}
else if(int_value == 1)
{
IedServer_updateBooleanAttributeValue(server, da, true);
}
else
{
LOG_E("Invalid boolean value %s", (char *)value);
}
}
LOCAL void model_da_value_update_INT32(IedServer server, DataAttribute *da, void *value)
{
if(NULL == server || NULL == da || NULL == value || strlen((char*)value) == 0)
{
// LOG_E("server, da or value is NULL");
return;
}
IedServer_updateInt32AttributeValue(server, da, atoi((char*)value));
}
LOCAL void model_da_value_update_INT32U(IedServer server, DataAttribute *da, void *value)
{
if(NULL == server || NULL == da || NULL == value || strlen((char*)value) == 0)
{
// LOG_E("server, da or value is NULL");
return;
}
IedServer_updateUnsignedAttributeValue(server, da, atoi((char*)value));
}
LOCAL void model_da_value_update_FLOAT32(IedServer server, DataAttribute *da, void *value)
{
if(NULL == server || NULL == da || NULL == value || strlen((char*)value) == 0)
{
// LOG_E("server, da or value is NULL");
return;
}
IedServer_updateFloatAttributeValue(server, da, atof((char*)value));
}
LOCAL void model_da_value_update_Enum(IedServer server, DataAttribute *da, void *value)
{
if(NULL == server || NULL == da || NULL == value)
{
// LOG_E("server, da or value is NULL");
return;
}
LOG_I("da %p, name %s, value %d", da, da->name, *(int *)value);
// IedServer_updateInt32AttributeValue(server, da, *(int *)value);
da->mmsValue = MmsValue_newIntegerFromInt32(*(int *)value);
}
LOCAL void model_da_value_update_Visible_String(IedServer server, DataAttribute *da, void *value)
{
if(NULL == server || NULL == da || NULL == value || strlen((char*)value) == 0)
{
// LOG_E("server, da or value is NULL");
return;
}
IedServer_updateVisibleStringAttributeValue(server, da, (char*)value);
}
LOCAL void model_da_value_update_Unicode_String(IedServer server, DataAttribute *da, void *value)
{
if(NULL == server || NULL == da || NULL == value || strlen((char*)value) == 0)
{
// LOG_E("server, da or value is NULL");
return;
}
// LOG_I("da %p, value %s", da, (char*)value);
IedServer_updateAttributeValue(server, da, MmsValue_newMmsString((char*)value));
}
LOCAL void model_da_value_update_timesramp(IedServer server, DataAttribute *da, void *value)
{
if(NULL == server || NULL == da)
{
LOG_E("server or da is NULL");
return;
}
IedServer_updateUTCTimeAttributeValue(server, da, Hal_getTimeInMs());
}
// void model_dataAttribute_value_init(IedServer server, stru_icd &icd, std::string da_name, stru_DAI &DAI, stru_BDA &BDA_item)
// {
// if(NULL == server)
// {
// LOG_E("server is NULL");
// return;
// }
// DataAttribute *da = DAI.DA;
// if(NULL == da)
// {
// LOG_E("DA is NULL");
// return;
// }
// // LOG_I("daname %s, btype %s, value %s, da %p", da_name.c_str(), BDA_item.bType.c_str(), DAI.val.c_str(), da);
// if(BDA_item.bType.compare("Struct") == 0)
// {
// if(icd.map_daType.find(BDA_item.type) == icd.map_daType.end())
// {
// LOG_E("DAType %s not found in ICD", BDA_item.type.c_str());
// return;
// }
// std::map<std::string, stru_DAI>::iterator it_dai;
// for(it_dai = DAI.map_daI.begin(); it_dai != DAI.map_daI.end(); it_dai++)
// {
// model_dataAttribute_value_init(server, icd, it_dai->first, it_dai->second, icd.map_daType[BDA_item.type].map_bda[it_dai->first]);
// }
// }
// else if(BDA_item.bType.compare("Enum") == 0)
// {
// if(icd.map_enumType.find(BDA_item.type) == icd.map_enumType.end())
// {
// LOG_E("EnumType %s not found in ICD", BDA_item.type.c_str());
// return;
// }
// if(DAI.val.empty())
// {
// int temp = 0;
// model_da_value_update_Enum(server, da, (void*)&temp);
// // LOG_I("Enum value is empty, set to 0");
// return;
// }
// else
// {
// // LOG_I("Enum value %s", DAI.val.c_str());
// }
// std::map<int, std::string>::iterator it_enum;
// for(it_enum = icd.map_enumType[BDA_item.type].map_enumVal.begin(); it_enum != icd.map_enumType[BDA_item.type].map_enumVal.end(); it_enum++)
// {
// if(it_enum->second.compare(DAI.val) == 0)
// {
// model_da_value_update_Enum(server, da, (void*)&it_enum->first);
// }
// else if(it_enum->first == atoi(DAI.val.c_str()))
// {
// model_da_value_update_Enum(server, da, (void*)&it_enum->first);
// }
// }
// }
// else
// {
// for(int i = 0; i < g_iec61850s_value_update_cb_count; i++)
// {
// if(BDA_item.bType.compare(g_iec61850s_value_update_cb[i].btype) == 0)
// {
// if(g_iec61850s_value_update_cb[i].value_update_cb != NULL)
// {
// g_iec61850s_value_update_cb[i].value_update_cb(server, da, (void*)DAI.val.c_str());
// }
// else
// {
// LOG_E("No value update callback for bType %s", BDA_item.bType.c_str());
// }
// break;
// }
// }
// }
// }
// void model_dataAttribute_value_init(IedServer server, stru_icd &icd, std::string da_name, stru_DAI &DAI, stru_DA &DA_item)
// {
// if(NULL == server)
// {
// LOG_E("server is NULL");
// return;
// }
// DataAttribute *da = DAI.DA;
// if(NULL == da)
// {
// LOG_E("DA is NULL");
// return;
// }
// // LOG_I("daname %s, btype %s, value %s, da %p", da_name.c_str(), DA_item.bType.c_str(), DAI.val.c_str(), da);
// if(DA_item.bType.compare("Struct") == 0)
// {
// if(icd.map_daType.find(DA_item.type) == icd.map_daType.end())
// {
// LOG_E("DAType %s not found in ICD", DA_item.type.c_str());
// return;
// }
// std::map<std::string, stru_DAI>::iterator it_dai;
// for(it_dai = DAI.map_daI.begin(); it_dai != DAI.map_daI.end(); it_dai++)
// {
// model_dataAttribute_value_init(server, icd, it_dai->first, it_dai->second, icd.map_daType[DA_item.type].map_bda[it_dai->first]);
// }
// }
// else if(DA_item.bType.compare("Enum") == 0)
// {
// if(icd.map_enumType.find(DA_item.type) == icd.map_enumType.end())
// {
// LOG_E("EnumType %s not found in ICD", DA_item.type.c_str());
// return;
// }
// if(DAI.val.empty())
// {
// int temp = 0;
// model_da_value_update_Enum(server, da, (void*)&temp);
// LOG_I("Enum value is empty, set to 0");
// return;
// }
// else
// {
// // LOG_I("Enum value %s", DAI.val.c_str());
// }
// std::map<int, std::string>::iterator it_enum;
// for(it_enum = icd.map_enumType[DA_item.type].map_enumVal.begin(); it_enum != icd.map_enumType[DA_item.type].map_enumVal.end(); it_enum++)
// {
// if(it_enum->second.compare(DAI.val) == 0)
// {
// model_da_value_update_Enum(server, da, (void*)&it_enum->first);
// }
// else if(it_enum->first == atoi(DAI.val.c_str()))
// {
// model_da_value_update_Enum(server, da, (void*)&it_enum->first);
// }
// }
// }
// else
// {
// for(int i = 0; i < g_iec61850s_value_update_cb_count; i++)
// {
// if(DA_item.bType.compare(g_iec61850s_value_update_cb[i].btype) == 0)
// {
// if(g_iec61850s_value_update_cb[i].value_update_cb != NULL)
// {
// g_iec61850s_value_update_cb[i].value_update_cb(server, da, (void*)DAI.val.c_str());
// }
// else
// {
// LOG_E("No value update callback for bType %s", DA_item.bType.c_str());
// }
// break;
// }
// }
// }
// }
// /*
// * model_dataObject_value_init - initialize the values of the data objects in the IED model
// input: server - the IedServer object
// icd - the ICD object, contains all the information of the model and values
// lnType_item - the LNodeType object, contains all the information of the logical node type
// map_all_do - the map of all data objects in the IED model
// map_doI - the map of data object instances in the IED model
// output:
// return: 0 - success, other - failure
// */
// int model_dataObject_value_init(IedServer server, stru_icd &icd, stru_LNodeType &lnType_item, std::map<std::string, stru_all_DO *> &map_all_do, std::map<std::string, stru_DOI> &map_doI)
// {
// for(std::map<std::string, stru_DOI>::iterator it_doI = map_doI.begin(); it_doI != map_doI.end(); it_doI++)
// {
// // LOG_I("doiname %s", it_doI->first.c_str());
// if(map_all_do.find(it_doI->first) == map_all_do.end())
// {
// LOG_E("Data object %s not found in map_all_do", it_doI->first.c_str());
// continue;
// }
// stru_all_DO &all_DO_item = *map_all_do[it_doI->first];
// it_doI->second.DO = all_DO_item.DO;
// if(lnType_item.map_do.find(it_doI->first) == lnType_item.map_do.end())
// {
// LOG_E("Data object %s not found in lnType_item.map_do", it_doI->first.c_str());
// continue;
// }
// stru_DO &DO_item = lnType_item.map_do[it_doI->first];
// if(icd.map_doType.find(DO_item.type) == icd.map_doType.end())
// {
// LOG_E("DOType %s not found in ICD", DO_item.type.c_str());
// continue;
// }
// stru_DOType &DOType_item = icd.map_doType[DO_item.type];
// for(std::map<std::string, stru_DAI>::iterator it_dai = it_doI->second.map_daI.begin(); it_dai != it_doI->second.map_daI.end(); it_dai++)
// {
// if(all_DO_item.map_all_sdo.find(it_dai->first) != all_DO_item.map_all_sdo.end())
// {
// if(DOType_item.map_sdo.find(it_dai->first) == DOType_item.map_sdo.end())
// {
// LOG_E("SDO %s not found in DOType %s", it_dai->first.c_str(), DO_item.type.c_str());
// continue;
// }
// }
// else if(all_DO_item.map_all_da.find(it_dai->first) != all_DO_item.map_all_da.end())
// {
// if(DOType_item.map_da.find(it_dai->first) == DOType_item.map_da.end())
// {
// LOG_E("DA %s not found in DOType %s", it_dai->first.c_str(), DO_item.type.c_str());
// continue;
// }
// model_dataAttribute_value_init(server, icd, it_dai->first, it_dai->second, DOType_item.map_da[it_dai->first]);
// }
// }
// }
// return 0;
// }
// /*
// * iec61850s_value_update - update the values of the data attributes in the IED model
// input: server - the IedServer object
// icd - the ICD object, contains all the information of the model and values
// output:
// return:
// */
// void iec61850s_value_update(IedServer server, stru_icd &icd)
// {
// if(NULL == server)
// {
// LOG_E("server is NULL");
// return;
// }
// // for each logical device in the IED model
// for(std::map<std::string, stru_LDevice>::iterator it_ld = icd.ied.map_ldevice.begin(); it_ld!= icd.ied.map_ldevice.end(); it_ld++)
// {
// // LOG_I("ldname %s", it_ld->first.c_str());
// // LLN0
// if(icd.map_lnType.find(it_ld->second.ln0.lnType) != icd.map_lnType.end())
// {
// // LOG_I("ln0 lnType %s", it_ld->second.ln0.lnType.c_str());
// model_dataObject_value_init(server, icd, icd.map_lnType[it_ld->second.ln0.lnType], it_ld->second.ln0.map_all_do, it_ld->second.ln0.map_doI);
// }
// else
// {
// LOG_E("lnType %s not found in ICD", it_ld->second.ln0.lnType.c_str());
// }
// // for each logical node in the logical device
// for(std::vector<stru_LN>::iterator it_ln = it_ld->second.vec_ln.begin(); it_ln != it_ld->second.vec_ln.end(); it_ln++)
// {
// if(icd.map_lnType.find(it_ln->lnType) != icd.map_lnType.end())
// {
// // LOG_I("ln lnType %s", it_ln->lnType.c_str());
// model_dataObject_value_init(server, icd, icd.map_lnType[it_ln->lnType], it_ln->map_all_do, it_ln->map_doI);
// }
// else
// {
// LOG_E("lnType %s not found in ICD", it_ln->lnType.c_str());
// }
// }
// }
// }
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 struct
{
const char *bType;
void (*value_init)(DataAttribute *da, void *value);
}g_iec61850s_value_init_cb[] =
{
{"BOOLEAN", mms_s_da_value_init_BOOLEAN},
{"INT8", NULL},
{"INT16", NULL},
{"INT32", mms_s_da_value_init_INT32},
{"INT64", NULL},
{"INT128", NULL},
{"INT8U", mms_s_da_value_init_INT32U},
{"INT16U", NULL},
{"INT32U", mms_s_da_value_init_INT32U},
{"FLOAT32", mms_s_da_value_init_FLOAT32},
{"FLOAT64", NULL},
{"Enum", NULL},
{"Octet64", NULL},
{"Octet6", NULL},
{"Octet8", NULL},
{"VisString32", mms_s_da_value_init_Visible_String},
{"VisString64", mms_s_da_value_init_Visible_String},
{"VisString65", mms_s_da_value_init_Visible_String},
{"VisString129", mms_s_da_value_init_Visible_String},
{"VisString255", mms_s_da_value_init_Visible_String},
{"Unicode255", mms_s_da_value_init_Unicode_String},
{"Timestamp", mms_s_da_value_init_Timestamp},
{"Quality", NULL},
{"Check", NULL},
{"CodedEnum", NULL},
{"BitString", NULL},
{"Struct", NULL},
{"EntryTime", NULL},
{"PhyComAddr", NULL},
{"Currency", NULL},
{"OptFlds", NULL},
{"TrgOps", NULL},
{"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]);
LOCAL void mms_s_da_value_init_BOOLEAN(DataAttribute *da, void *value)
{
if(NULL == da)
{
LOG_E("da is NULL");
return;
}
if(value == NULL || strlen((char*)value) == 0 || strcmp((char*)value, "false") == 0 || strcmp((char*)value, "0") == 0)
{
da->mmsValue = MmsValue_newBoolean(false);
}
if(value != NULL && (strcmp((char*)value, "true") == 0 || strcmp((char*)value, "1") == 0))
{
da->mmsValue = MmsValue_newBoolean(true);
}
}
LOCAL void mms_s_da_value_init_INT32(DataAttribute *da, void *value)
{
if(NULL == da)
{
LOG_E("da is NULL");
return;
}
if(value == NULL || strlen((char*)value) == 0)
{
da->mmsValue = MmsValue_newIntegerFromInt32(0);
}
else
{
da->mmsValue = MmsValue_newIntegerFromInt32(atoi((char*)value));
}
}
LOCAL void mms_s_da_value_init_INT32U(DataAttribute *da, void *value)
{
if(NULL == da)
{
LOG_E("da is NULL");
return;
}
if(value == NULL || strlen((char*)value) == 0)
{
da->mmsValue = MmsValue_newUnsignedFromUint32(0);
}
else
{
da->mmsValue = MmsValue_newUnsignedFromUint32(atoi((char*)value));
}
}
LOCAL void mms_s_da_value_init_FLOAT32(DataAttribute *da, void *value)
{
if(NULL == da)
{
LOG_E("da is NULL");
return;
}
if(value == NULL || strlen((char*)value) == 0)
{
da->mmsValue = MmsValue_newFloat(0.0);
}
else
{
da->mmsValue = MmsValue_newFloat(atof((char*)value));
}
}
LOCAL void mms_s_da_value_init_Visible_String(DataAttribute *da, void *value)
{
if(NULL == da)
{
LOG_E("da is NULL");
return;
}
if(value == NULL || strlen((char*)value) == 0)
{
da->mmsValue = MmsValue_newVisibleString("");
}
else
{
da->mmsValue = MmsValue_newVisibleString((char*)value);
}
}
LOCAL void mms_s_da_value_init_Unicode_String(DataAttribute *da, void *value)
{
if(NULL == da)
{
LOG_E("da is NULL");
return;
}
if(value == NULL || strlen((char*)value) == 0)
{
da->mmsValue = MmsValue_newMmsString("");
}
else
{
da->mmsValue = MmsValue_newMmsString((char*)value);
}
}
LOCAL void mms_s_da_value_init_Timestamp(DataAttribute *da, void *value)
{
if(NULL == da)
{
LOG_E("da is NULL");
return;
}
da->mmsValue = MmsValue_newUtcTimeByMsTime(Hal_getTimeInMs());
}
LOCAL void mms_s_da_value_init_Dbpos(DataAttribute *da, void *value)
{
if(NULL == da)
{
LOG_E("da is NULL");
return;
}
Dbpos pos = DBPOS_INTERMEDIATE_STATE;
if(value == NULL || strlen((char*)value) == 0)
{
pos = DBPOS_INTERMEDIATE_STATE;
}
else
{
int i = atoi((char*)value);
if(i == 0)
{
pos = DBPOS_INTERMEDIATE_STATE;
}
else if(i == 1)
{
pos = DBPOS_OFF;
}
else if(i == 2)
{
pos = DBPOS_ON;
}
else if(i == 3)
{
pos = DBPOS_BAD_STATE;
}
else
{
pos = DBPOS_BAD_STATE;
}
}
Dbpos_toMmsValue(da->mmsValue, pos);
LOG_I("da %s-%s, value %s, pos %d", da->parent->name, da->name, (char *)value, pos);
}
LOCAL void mms_s_da_values_init(stru_icd &icd, std::string da_name, stru_all_DA *p_all_da)
{
if(NULL == p_all_da)
{
LOG_E("da_name %s p_all_da is NULL", da_name.c_str());
return;
}
for(std::map<std::string, stru_all_DA *>::iterator it_da = p_all_da->map_all_da.begin(); it_da != p_all_da->map_all_da.end(); it_da++)
{
mms_s_da_values_init(icd, it_da->first, it_da->second);
}
if(p_all_da->bType.compare("Struct") == 0)
{
}
else if(p_all_da->bType.compare("Enum") == 0)
{
if(icd.map_enumType.find(p_all_da->type) == icd.map_enumType.end())
{
LOG_E("EnumType %s not found in ICD", p_all_da->type.c_str());
return;
}
std::map<int, std::string>::iterator it_enum;
for(it_enum = icd.map_enumType[p_all_da->type].map_enumVal.begin(); it_enum != icd.map_enumType[p_all_da->type].map_enumVal.end(); it_enum++)
{
if(it_enum->second.compare(p_all_da->val) == 0)
{
p_all_da->DA->mmsValue = MmsValue_newIntegerFromInt32(it_enum->first);
return;
}
}
if(icd.map_enumType[p_all_da->type].map_enumVal.find(atoi(p_all_da->val.c_str())) != icd.map_enumType[p_all_da->type].map_enumVal.end())
{
p_all_da->DA->mmsValue = MmsValue_newIntegerFromInt32(atoi(p_all_da->val.c_str()));
return;
}
p_all_da->DA->mmsValue = MmsValue_newIntegerFromInt32(0);
// LOG_I("Enum value %s not found in EnumType %s, set to 0", p_all_da->val.c_str(), p_all_da->type.c_str());
}
else
{
for(int i = 0; i < g_iec61850s_value_init_cb_count; i++)
{
if(p_all_da->bType.compare(g_iec61850s_value_init_cb[i].bType) == 0)
{
if(NULL != g_iec61850s_value_init_cb[i].value_init)
{
// LOG_I("BDAType %s, value %s", p_all_da->bType.c_str(), p_all_da->val.c_str());
g_iec61850s_value_init_cb[i].value_init(p_all_da->DA, (void *)p_all_da->val.c_str());
}
else
{
// LOG_E("btype %s, value_init is NULL", p_all_da->bType.c_str());
}
return;
}
}
LOG_E("BDAType %s not found in ICD", p_all_da->bType.c_str());
}
}
LOCAL void mms_s_do_values_init(stru_icd &icd, std::map<std::string, stru_all_DO *> &map_all_do)
{
for(std::map<std::string, stru_all_DO *>::iterator it_do = map_all_do.begin(); it_do != map_all_do.end(); it_do++)
{
for(std::map<std::string, stru_all_DO *>::iterator it_sdo = it_do->second->map_all_sdo.begin(); it_sdo != it_do->second->map_all_sdo.end(); it_sdo++)
{
mms_s_do_values_init(icd, it_sdo->second->map_all_sdo);
}
for(std::map<std::string, stru_all_DA *>::iterator it_da = it_do->second->map_all_da.begin(); it_da != it_do->second->map_all_da.end(); it_da++)
{
mms_s_da_values_init(icd, it_da->first, it_da->second);
}
}
}
void mms_s_values_init()
{
stru_icd *p_icd = mms_s_get_icd_ptr();
if(NULL == p_icd)
{
LOG_E("p_icd is NULL");
return;
}
for(std::map<std::string, stru_LDevice>::iterator it_ld = p_icd->ied.map_ldevice.begin(); it_ld!= p_icd->ied.map_ldevice.end(); it_ld++)
{
mms_s_do_values_init(*p_icd, it_ld->second.ln0.map_all_do);
for(std::vector<stru_LN>::iterator it_ln = it_ld->second.vec_ln.begin(); it_ln != it_ld->second.vec_ln.end(); it_ln++)
{
mms_s_do_values_init(*p_icd, it_ln->map_all_do);
}
}
}

View File

@ -29,7 +29,8 @@ LOCAL std::vector<stru_app> g_vec_app =
{"app_self_ptl", 0, app_self_ptl_init1, app_self_ptl_init2, (app_func_cb)app_self_ptl, NULL, 0, NULL},
{"app_web_server", 0, app_web_server_init1, app_web_server_init2, (app_func_cb)app_web_server, NULL, 0, NULL},
{"app_iec61850m", 0, app_iec61850m_init1, app_iec61850m_init2, (app_func_cb)app_iec61850m, NULL, 0, NULL},
{"app_iec61850s", 0, app_iec61850s_init1, app_iec61850s_init2, (app_func_cb)app_iec61850s, NULL, 0, NULL},
};

View File

@ -145,7 +145,7 @@ int dc_get_in_signal_info(const std::string &saddr, std::string &desc, uint8_t &
return -1;
}
int dc_get_ao_siganl_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param &param, uint8_t &ctrl_type, std::vector<void *> &vec_p_data, std::vector<void *> &vec_p_default_data)
int dc_get_ao_signal_info(const std::string &saddr, std::string &desc, uint8_t &data_type, stru_signal_param &param, uint8_t &ctrl_type, std::vector<void *> &vec_p_data, std::vector<void *> &vec_p_default_data)
{
stru_signal *p_signal = dc_find_signal(XXH3_128bits(saddr.c_str(), saddr.length()), g_datacenter.signal_ao);
if(p_signal == nullptr)
@ -1054,7 +1054,7 @@ int dc_signal_out_with_callback(const std::string &saddr, const std::string &des
return dc_signal_add_to_map(signal, g_datacenter.signal_out);
}
int dc_signal_in(const std::string &saddr, const std::string &desc, const std::string &link_saddr, uint8_t data_type, void **p_data)
int dc_signal_in(const std::string &saddr, const std::string &desc, const std::string &link_saddr, void **p_data)
{
if(p_data == nullptr)
{
@ -1074,7 +1074,6 @@ int dc_signal_in(const std::string &saddr, const std::string &desc, const std::s
signal.hash = XXH3_128bits(saddr.c_str(), saddr.length());
signal.saddr.assign(saddr);
signal.desc.assign(desc);
signal.data_type = data_type;
if(link_saddr.empty())
{
@ -1090,6 +1089,7 @@ int dc_signal_in(const std::string &saddr, const std::string &desc, const std::s
}
(*p_data) = p_signal_out->vec_p_data[0];
signal.data_type = p_signal_out->data_type;
signal.vec_p_data.push_back((*p_data));
bool found = false;
@ -1114,7 +1114,7 @@ int dc_signal_in(const std::string &saddr, const std::string &desc, const std::s
return dc_signal_add_to_map(signal, g_datacenter.signal_in);
}
int dc_signal_in_with_callback(const std::string &saddr, const std::string &desc, const std::string &link_saddr, uint8_t data_type, void **p_data, out_signal_change_cb cb)
int dc_signal_in_with_callback(const std::string &saddr, const std::string &desc, const std::string &link_saddr, void **p_data, out_signal_change_cb cb)
{
if(p_data == nullptr)
{
@ -1133,7 +1133,6 @@ int dc_signal_in_with_callback(const std::string &saddr, const std::string &desc
signal.hash = XXH3_128bits(saddr.c_str(), saddr.length());
signal.saddr.assign(saddr);
signal.desc.assign(desc);
signal.data_type = data_type;
if(link_saddr.empty())
{
@ -1149,6 +1148,7 @@ int dc_signal_in_with_callback(const std::string &saddr, const std::string &desc
}
(*p_data) = p_signal_out->vec_p_data[0];
signal.data_type = p_signal_out->data_type;
signal.vec_p_data.push_back((*p_data));
if(nullptr != cb)
@ -1222,7 +1222,7 @@ int dc_signal_ao(const std::string &saddr, const std::string &desc, uint8_t data
return -1;
}
int dc_signal_ao_link_with_callback(const std::string &saddr, uint8_t data_type, void **p_data, signal_change_cb cb)
int dc_signal_ao_link_with_callback(const std::string &saddr, void **p_data, signal_change_cb cb)
{
if(p_data == nullptr)
{
@ -1425,18 +1425,18 @@ int dc_signal_param(const std::string &saddr, const std::string &desc, uint8_t d
return -1;
}
int dc_signal_param_link_with_callback(const std::string &saddr, uint8_t data_type, std::vector<void *> &vec_p_data, signal_change_cb cb)
int dc_signal_param_link_with_callback(const std::string &saddr, std::vector<void *> &vec_p_data, signal_change_cb cb)
{
XXH128_hash_t hash = XXH3_128bits(saddr.c_str(), saddr.length());
stru_signal *p_signal = dc_find_signal(hash, g_datacenter.signal_param);
if(p_signal != nullptr)
{
if(p_signal->data_type != data_type)
{
LOG_E("saddr %s data type %s(%d) not match %s(%d)",
saddr.c_str(), dc_get_data_type_str_by_id(p_signal->data_type), p_signal->data_type, dc_get_data_type_str_by_id(data_type), data_type);
return -1;
}
// if(p_signal->data_type != data_type)
// {
// LOG_E("saddr %s data type %s(%d) not match %s(%d)",
// saddr.c_str(), dc_get_data_type_str_by_id(p_signal->data_type), p_signal->data_type, dc_get_data_type_str_by_id(data_type), data_type);
// return -1;
// }
if(cb)
{
@ -1581,7 +1581,7 @@ int dc_signal_yk(const std::string &saddr, const std::string &desc, uint8_t data
return -1;
}
int dc_signal_yk_link_with_callback(const std::string &saddr, uint8_t data_type, void **p_data, signal_change_cb cb)
int dc_signal_yk_link_with_callback(const std::string &saddr, void **p_data, signal_change_cb cb)
{
if(p_data == nullptr)
{

View File

@ -434,7 +434,7 @@ int app_iec_init2(void *arg)
for(uint32_t j = 0; j < p_vec->size(); j++)
{
void *p_data = nullptr;
ret = dc_signal_in_with_callback(p_vec->at(j).saddr, p_vec->at(j).desc, p_vec->at(j).link, p_vec->at(j).type, &p_data, iec_signal_link_change);
ret = dc_signal_in_with_callback(p_vec->at(j).saddr, p_vec->at(j).desc, p_vec->at(j).link, &p_data, iec_signal_link_change);
if(ret != 0)
{
LOG_E("dc_signal_in failed, saddr %s, desc %s, link %s, type %s",
@ -452,7 +452,7 @@ int app_iec_init2(void *arg)
for(uint32_t j = 0; j < p_vec->size(); j++)
{
void *p_data = nullptr;
ret = dc_signal_yk_link_with_callback(p_vec->at(j).saddr, p_vec->at(j).type, &p_data, iec_signal_ctrl_change);
ret = dc_signal_yk_link_with_callback(p_vec->at(j).saddr, &p_data, iec_signal_ctrl_change);
if(ret != 0)
{
LOG_E("dc_signal_yk_link failed, saddr %s, type %s",

View File

@ -199,7 +199,7 @@ void iec61850m_init()
}
LOCAL int iec61850m_signal_change_decode(std::string saddr, SIGNAL_CTRL_STEP step, uint8_t data_type, void *p_data, uint8_t &ctrl_type, uint8_t &mms_type)
LOCAL int iec61850m_signal_change_decode(std::string saddr, SIGNAL_CTRL_STEP step, uint8_t data_type, void *p_data, uint8_t &ctrl_type, uint8_t &mms_type, std::string signal_type)
{
std::string value = "";
if(p_data)
@ -234,7 +234,10 @@ LOCAL int iec61850m_signal_change_decode(std::string saddr, SIGNAL_CTRL_STEP ste
break;
case SIGNAL_CTRL_STEP::DIRECT:
step_str = "DIRECT";
ctrl_type = _MMS_M_EVENT_AO_WRITE;
if(signal_type == "co")
ctrl_type = _MMS_M_EVENT_CO_DIRECT;
else
ctrl_type = _MMS_M_EVENT_AO_WRITE;
break;
case SIGNAL_CTRL_STEP::CANCEL:
step_str = "CANCEL";
@ -255,7 +258,7 @@ LOCAL void iec61850m_signal_co_change_callback(std::string saddr, SIGNAL_CTRL_ST
uint8_t mms_type = 0;
uint8_t ctrl_type = 0;
if(0 != iec61850m_signal_change_decode(saddr, step, data_type, p_data, ctrl_type, mms_type))
if(0 != iec61850m_signal_change_decode(saddr, step, data_type, p_data, ctrl_type, mms_type, "co"))
{
return;
}
@ -282,7 +285,7 @@ LOCAL void iec61850m_signal_ao_change_callback(std::string saddr, SIGNAL_CTRL_ST
uint8_t mms_type = 0;
uint8_t ctrl_type = 0;
if(0 != iec61850m_signal_change_decode(saddr, step, data_type, p_data, ctrl_type, mms_type))
if(0 != iec61850m_signal_change_decode(saddr, step, data_type, p_data, ctrl_type, mms_type, "ao"))
{
return;
}
@ -314,7 +317,7 @@ LOCAL void iec61850m_signal_param_change_callback(std::string saddr, SIGNAL_CTRL
uint8_t mms_type = 0;
uint8_t ctrl_type = 0;
if(0 != iec61850m_signal_change_decode(saddr, step, data_type, p_data, ctrl_type, mms_type))
if(0 != iec61850m_signal_change_decode(saddr, step, data_type, p_data, ctrl_type, mms_type, "param"))
{
return;
}
@ -490,7 +493,7 @@ int app_iec61850m_init1(void *arg)
int app_iec61850m_init2(void *arg)
{
dc_signal_in("iec61850m.iec_run_cnt_in", "iec61850m.iec_run_cnt_in", "iec.run_cnt", DATA_TYPE_U32, (void **)&p_iec_run_cnt);
dc_signal_in("iec61850m.iec_run_cnt_in", "iec61850m.iec_run_cnt_in", "iec.run_cnt", (void **)&p_iec_run_cnt);
MY_LOG_I("p_iec_run_cnt %p", p_iec_run_cnt);
return 0;
@ -500,7 +503,7 @@ void *app_iec61850m(void *arg)
{
if(NULL == arg)
{
LOG_E("app_com_scan arg null");
LOG_E("app_iec61850m arg null");
return NULL;
}

View File

@ -0,0 +1,5 @@
#pragma once
#include "myBase.h"
#include "mySystem.h"
#include "myMms_s.h"

View File

@ -0,0 +1,298 @@
#include "iec61850_common.h"
#include "iec61850s.h"
#include "myLog.h"
#include "myCmd.h"
LOCAL std::vector<stru_mms_s_control> vec_control =
{
{"iec61850m.prj.co.0", "遥控01", 4},
{"iec61850m.prj.co.1", "遥控02", 4},
{"iec61850m.prj.co.2", "遥控03", 4},
{"iec61850m.prj.co.3", "遥控04", 4},
};
LOCAL std::vector<stru_mms_s_setting> vec_setting =
{
{
.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,
}
};
LOCAL std::vector<stru_mms_s_param> vec_param =
{
{
.base = {.saddr = "iec61850m.prj.param.0", .desc = "定值01", .type = DATA_TYPE_F32},
.data = NULL,
},
};
void iec61850s_control_callback(stru_mms_s_control *p_control, uint8_t state)
{
if(NULL == p_control)
{
LOG_E("p_control is NULL");
return;
}
LOG_I("control callback called saddr: %s, state: %i", p_control->saddr, state);
uint8_t temp_st = 0;
stru_signal_ctrl ctrl = {
.step = SIGNAL_CTRL_STEP::READY,
.type = SIGNAL_CTRL_TYPE::NONE,
.data_type = DATA_TYPE_U8,
.p_data = &temp_st,
};
if(p_control->ctrl_model == CONTROL_MODEL_DIRECT_NORMAL || p_control->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))
{
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)
{
ctrl.type = SIGNAL_CTRL_TYPE::SBO_NORMAL;
if(0 != dc_signal_yk_set_status(p_control->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))
{
MY_LOG_E("dc_signal_yk_set_status failed");
return;
}
}
else if(p_control->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)
{
if(NULL == p_setting || NULL == p_data)
{
LOG_E("p_setting or p_data is NULL");
return;
}
LOG_I("setting callback called saddr: %s, data: %s", p_setting->base.saddr, p_data);
uint8_t temp_val[128] = {0};
uint8_t temp_ctrl_val[128] = {0};
dc_set_signal_val_from_str(temp_val, p_setting->base.type, p_data);
stru_signal_ctrl ctrl = {
.step = SIGNAL_CTRL_STEP::READY,
.type = SIGNAL_CTRL_TYPE::NONE,
.data_type = p_setting->base.type,
.p_data = temp_ctrl_val,
};
if(p_setting->base.ctrl_model == SIGNAL_CTRL_TYPE::DIRECT_NORMAL)
{
ctrl.type = SIGNAL_CTRL_TYPE::DIRECT_NORMAL;
if(0 != dc_signal_ao_set_val(p_setting->base.saddr, SIGNAL_CTRL_STEP::DIRECT, ctrl, temp_val))
{
MY_LOG_E("dc_signal_ao_set_val failed");
return;
}
}
else if(p_setting->base.ctrl_model == SIGNAL_CTRL_TYPE::SBO_NORMAL)
{
ctrl.type = SIGNAL_CTRL_TYPE::SBO_NORMAL;
if(0 != dc_signal_ao_set_val(p_setting->base.saddr, SIGNAL_CTRL_STEP::SELECT, ctrl, temp_val))
{
MY_LOG_E("dc_signal_ao_set_val select failed");
return;
}
if(0 != dc_signal_ao_set_val(p_setting->base.saddr, SIGNAL_CTRL_STEP::DIRECT, ctrl, temp_val))
{
MY_LOG_E("dc_signal_ao_set_val direct failed");
return;
}
}
}
void iec61850s_param_callback(stru_mms_s_param *p_param, const char *p_data, int setting_zone)
{
if(NULL == p_param || NULL == p_data)
{
LOG_E("p_param or p_data is NULL");
return;
}
LOG_I("param callback called saddr: %s, data: %s, setting_zone: %i", p_param->base.saddr, p_data, setting_zone);
uint8_t temp_val[128] = {0};
uint8_t temp_ctrl_val[128] = {0};
dc_set_signal_val_from_str(temp_val, p_param->base.type, p_data);
stru_signal_ctrl ctrl = {
.step = SIGNAL_CTRL_STEP::READY,
.type = SIGNAL_CTRL_TYPE::NONE,
.data_type = p_param->base.type,
.p_data = temp_ctrl_val,
};
if(p_param->base.ctrl_model == SIGNAL_CTRL_TYPE::DIRECT_NORMAL)
{
ctrl.type = SIGNAL_CTRL_TYPE::DIRECT_NORMAL;
if(0 != dc_signal_param_set_val(p_param->base.saddr, SIGNAL_CTRL_STEP::DIRECT, ctrl, setting_zone, temp_val))
{
MY_LOG_E("dc_signal_param_set_val failed");
return;
}
}
else if(p_param->base.ctrl_model == SIGNAL_CTRL_TYPE::SBO_NORMAL)
{
ctrl.type = SIGNAL_CTRL_TYPE::SBO_NORMAL;
if(0 != dc_signal_param_set_val(p_param->base.saddr, SIGNAL_CTRL_STEP::SELECT, ctrl, setting_zone, temp_val))
{
MY_LOG_E("dc_signal_param_set_val select failed");
return;
}
if(0 != dc_signal_param_set_val(p_param->base.saddr, SIGNAL_CTRL_STEP::DIRECT, ctrl, setting_zone, temp_val))
{
MY_LOG_E("dc_signal_param_set_val direct failed");
return;
}
}
}
int app_iec61850s_init1(void *arg)
{
mms_s_dbg_switch(true);
mms_s_control_register(vec_control.data(), vec_control.size(), iec61850s_control_callback);
return 0;
}
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 != dc_signal_ao_link_with_callback(it->base.saddr, (void **)&it->data, NULL))
{
MY_LOG_E("dc_signal_ao_link_with_callback failed");
return -1;
}
std::string desc = "";
uint8_t data_type = 0;
stru_signal_param param = {};
uint8_t ctrl_type = 0;
std::vector<void *> vec_p_data = {};
std::vector<void *> vec_p_default_data = {};
dc_get_ao_signal_info(it->base.saddr, desc, data_type, param, ctrl_type, vec_p_data, vec_p_default_data);
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::vector<void *> vec_p_data = {};
// if(0 != dc_signal_param_link_with_callback(it->base.saddr, vec_p_data, NULL))
// {
// MY_LOG_E("dc_signal_param_link_with_callback failed");
// return -1;
// }
std::string desc = "";
uint8_t data_type = 0;
stru_signal_param param = {};
uint8_t ctrl_type = 0;
std::vector<void *> vec_p_data = {};
std::vector<void *> vec_p_default_data = {};
if(0 != dc_get_param_signal_info(it->base.saddr, desc, data_type, param, ctrl_type, vec_p_data, vec_p_default_data))
{
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);
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");
return -1;
}
return 0;
}
void *app_iec61850s(void *arg)
{
if(NULL == arg)
{
LOG_E("app_iec61850s arg null");
return NULL;
}
stru_app *p_app = (stru_app *)arg;
uint32_t event;
stru_app_msg_queue *p_mq = NULL;
stru_msg_head *p_head = NULL;
stru_rtx_data *p_rtx = &p_app->rtx;
while (1)
{
task_event_recv(p_app->p_event,
EV_TIMER1 | EV_TIMER2 | EV_TIMER3 ,
TASK_EVENT_FLAG_OR | TASK_EVENT_FLAG_CLEAR,
TASK_EVENT_WAIT_FOREVER,
&event);
if(event & EV_TIMER1)
{
;
}
if(event & EV_TIMER2)
{
;
}
if(event & EV_TIMER3)
{
p_app->run_cnt++;
}
}
}

View File

@ -917,8 +917,6 @@ int self_ptl_do_signal_out(stru_app *p_app)
param.step = safeStringToFloat(p_param->p_param->step);
param.unit = p_param->p_param->unit;
// ret(saddr, p(saddr, p->name, p->type, p->p_data);
ret |= dc_signal_param(p_param->p_param->base.saddr, p_param->p_param->base.desc, p_param->p_param->type, param, SIGNAL_CTRL_TYPE::SBO_NORMAL, p_param->vec_p_data, p_param->vec_p_default_data, self_ptl_signal_change_callback);
}
}
@ -960,7 +958,7 @@ LOCAL uint32_t *p_iec_run_cnt_in = NULL;
int app_self_ptl_init2(void *arg)
{
dc_signal_in("self_ptl.iec_run_cnt_in", "self_ptl.iec_run_cnt_in", "iec.run_cnt", DATA_TYPE_U32, (void **)&p_iec_run_cnt_in);
dc_signal_in("self_ptl.iec_run_cnt_in", "self_ptl.iec_run_cnt_in", "iec.run_cnt", (void **)&p_iec_run_cnt_in);
MY_LOG_I("p_iec_run_cnt_in %p", p_iec_run_cnt_in);
return 0;

View File

@ -144,9 +144,9 @@ void add_signal(const std::string& saddr, const std::string& signal_type)
p_signals->back().p_param = new stru_signal_param;
p = &p_signals->back();
if(0 != dc_get_ao_siganl_info(saddr, p->desc, p->data_type, *p->p_param, p->ctrl_type, p->vec_p_data, p->vec_p_default_data))
if(0 != dc_get_ao_signal_info(saddr, p->desc, p->data_type, *p->p_param, p->ctrl_type, p->vec_p_data, p->vec_p_default_data))
{
LOG_E("add_signals: dc_get_ao_siganl_info failed, saddr = %s", saddr.c_str());
LOG_E("add_signals: dc_get_ao_signal_info failed, saddr = %s", saddr.c_str());
delete p->p_ctrl;
delete p->p_param;
@ -286,6 +286,16 @@ void set_signal_data(const std::string& saddr, const std::string& signal_type, c
return;
}
uint8_t data[128] = {0};
memset(data, 0, sizeof(data));
uint8_t data_type = dc_get_data_type_id_by_str(signal_type);
if(data_type == 0)
{
LOG_E("set_signal_data: invalid signal_type = %s", signal_type.c_str());
return;
}
dc_set_signal_val_from_str(data, data_type, signal_data);
if(signal_type == "out")
{
p_signals = &g_ws_out_signals;
@ -294,7 +304,7 @@ void set_signal_data(const std::string& saddr, const std::string& signal_type, c
stru_ws_signal *p_signal = &p_signals->at(i);
if(p_signal->saddr == saddr)
{
if(0 != dc_set_out_signal_val(saddr, (void *)signal_data.c_str()))
if(0 != dc_set_out_signal_val(saddr, (void *)data))
{
LOG_E("set_signal_data: dc_set_signal_val failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str());
return;
@ -311,8 +321,6 @@ void set_signal_data(const std::string& saddr, const std::string& signal_type, c
{
p_signals = &g_ws_yk_signals;
uint8_t ctrl_status = atoi(signal_data.c_str());
for(uint32_t i = 0; i < p_signals->size(); i++)
{
stru_ws_signal *p_signal = &p_signals->at(i);
@ -320,33 +328,33 @@ void set_signal_data(const std::string& saddr, const std::string& signal_type, c
{
if(p_signal->ctrl_type == SIGNAL_CTRL_TYPE::DIRECT_NORMAL)
{
if(0 != dc_signal_yk_set_status(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, (void *)&ctrl_status))
if(0 != dc_signal_yk_set_status(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, (void *)data))
{
LOG_E("set_signal_data: dc_signal_yk_set_status direct failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str());
return;
}
LOG_I("saddr %s, direct, value %d success !!!", saddr.c_str(), ctrl_status);
LOG_I("saddr %s, direct, value %d success !!!", saddr.c_str(), signal_data.c_str());
return;
}
else if(p_signal->ctrl_type == SIGNAL_CTRL_TYPE::SBO_NORMAL)
{
if(0 != dc_signal_yk_set_status(saddr, SIGNAL_CTRL_STEP::SELECT, *p_signal->p_ctrl, (void *)&ctrl_status))
if(0 != dc_signal_yk_set_status(saddr, SIGNAL_CTRL_STEP::SELECT, *p_signal->p_ctrl, (void *)data))
{
LOG_E("set_signal_data: dc_signal_yk_set_status select failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str());
return;
}
task_sleep_ms(1000);
MY_LOG_I("saddr %s, select value %d success !!!", saddr.c_str(), ctrl_status);
MY_LOG_I("saddr %s, select value %s success !!!", saddr.c_str(), signal_data.c_str());
if(0 != dc_signal_yk_set_status(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, (void *)&ctrl_status))
if(0 != dc_signal_yk_set_status(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, (void *)data))
{
LOG_E("set_signal_data: dc_signal_yk_set_status direct failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str());
return;
}
MY_LOG_I("saddr %s, direct value %d success", saddr.c_str(), ctrl_status);
MY_LOG_I("saddr %s, direct value %s success !!!", saddr.c_str(), signal_data.c_str());
return;
}
else
@ -361,8 +369,6 @@ void set_signal_data(const std::string& saddr, const std::string& signal_type, c
{
p_signals = &g_ws_ao_signals;
char temp_data[128] = {0};
for(uint32_t i = 0; i < p_signals->size(); i++)
{
stru_ws_signal *p_signal = &p_signals->at(i);
@ -370,10 +376,7 @@ void set_signal_data(const std::string& saddr, const std::string& signal_type, c
{
if(p_signal->ctrl_type == SIGNAL_CTRL_TYPE::DIRECT_NORMAL)
{
memset(temp_data, 0, sizeof(temp_data));
dc_set_signal_val_from_str(temp_data, p_signal->data_type, signal_data);
if(0 != dc_signal_ao_set_val(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, (void *)temp_data))
if(0 != dc_signal_ao_set_val(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, (void *)data))
{
LOG_E("set_signal_data: dc_signal_ao_set_val direct failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str());
return;
@ -384,10 +387,8 @@ void set_signal_data(const std::string& saddr, const std::string& signal_type, c
}
else if(p_signal->ctrl_type == SIGNAL_CTRL_TYPE::SBO_NORMAL)
{
memset(temp_data, 0, sizeof(temp_data));
dc_set_signal_val_from_str(temp_data, p_signal->data_type, signal_data);
if(0 != dc_signal_ao_set_val(saddr, SIGNAL_CTRL_STEP::SELECT, *p_signal->p_ctrl, (void *)temp_data))
if(0 != dc_signal_ao_set_val(saddr, SIGNAL_CTRL_STEP::SELECT, *p_signal->p_ctrl, (void *)data))
{
LOG_E("set_signal_data: dc_signal_ao_set_val select failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str());
return;
@ -395,7 +396,7 @@ void set_signal_data(const std::string& saddr, const std::string& signal_type, c
LOG_I("saddr %s, select, value %s success !!!", saddr.c_str(), signal_data.c_str());
if(0 != dc_signal_ao_set_val(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, (void *)temp_data))
if(0 != dc_signal_ao_set_val(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, (void *)data))
{
LOG_E("set_signal_data: dc_signal_ao_set_val direct failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str());
return;
@ -423,7 +424,7 @@ void set_signal_data(const std::string& saddr, const std::string& signal_type, c
{
if(p_signal->ctrl_type == SIGNAL_CTRL_TYPE::DIRECT_NORMAL)
{
if(0 != dc_signal_param_set_val(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, setting_zone, (void *)signal_data.c_str()))
if(0 != dc_signal_param_set_val(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, setting_zone, (void *)data))
{
LOG_E("set_signal_data: dc_signal_param_set_val direct failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str());
return;
@ -434,7 +435,7 @@ void set_signal_data(const std::string& saddr, const std::string& signal_type, c
}
else if(p_signal->ctrl_type == SIGNAL_CTRL_TYPE::SBO_NORMAL)
{
if(0 != dc_signal_param_set_val(saddr, SIGNAL_CTRL_STEP::SELECT, *p_signal->p_ctrl, setting_zone, (void *)signal_data.c_str()))
if(0 != dc_signal_param_set_val(saddr, SIGNAL_CTRL_STEP::SELECT, *p_signal->p_ctrl, setting_zone, (void *)data))
{
LOG_E("set_signal_data: dc_signal_param_set_val select failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str());
return;
@ -442,7 +443,7 @@ void set_signal_data(const std::string& saddr, const std::string& signal_type, c
LOG_I("saddr %s, select, value %s success !!!", saddr.c_str(), signal_data.c_str());
if(0 != dc_signal_param_set_val(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, setting_zone, (void *)signal_data.c_str()))
if(0 != dc_signal_param_set_val(saddr, SIGNAL_CTRL_STEP::DIRECT, *p_signal->p_ctrl, setting_zone, (void *)data))
{
LOG_E("set_signal_data: dc_signal_param_set_val direct failed, saddr = %s, signal_data = %s", saddr.c_str(), signal_data.c_str());
return;
@ -661,8 +662,6 @@ void ws_task()
cJSON_AddItemToObject(item, "saddr", cJSON_CreateString(p_signal->saddr.c_str()));
cJSON_AddItemToObject(item, "desc", cJSON_CreateString(p_signal->desc.c_str()));
cJSON_AddItemToObject(item, "type", cJSON_CreateString(dc_get_data_type_str_by_id(p_signal->data_type).c_str()));
// std::string val = dc_get_signal_val(p_signal->vec_p_data[0], p_signal->data_type);
// cJSON_AddItemToObject(item, "val", cJSON_CreateString(val.c_str()));
cJSON_AddItemToObject(item, "ctrl_type", cJSON_CreateNumber(p_signal->ctrl_type));
if(p_signal->p_param)
{
@ -670,7 +669,6 @@ void ws_task()
cJSON_AddItemToObject(item, "max", cJSON_CreateString(std::to_string(p_signal->p_param->max).c_str()));
cJSON_AddItemToObject(item, "step", cJSON_CreateString(std::to_string(p_signal->p_param->step).c_str()));
cJSON_AddItemToObject(item, "unit", cJSON_CreateString(p_signal->p_param->unit.c_str()));
// cJSON_AddItemToObject(item, "default", cJSON_CreateString(p_signal->p_param->default_value.c_str()));
}
std::string val = dc_get_signal_val(p_signal->vec_p_data[0], p_signal->data_type);
@ -699,8 +697,6 @@ void ws_task()
cJSON_AddItemToObject(item, "saddr", cJSON_CreateString(p_signal->saddr.c_str()));
cJSON_AddItemToObject(item, "desc", cJSON_CreateString(p_signal->desc.c_str()));
cJSON_AddItemToObject(item, "type", cJSON_CreateString(dc_get_data_type_str_by_id(p_signal->data_type).c_str()));
// std::string val = dc_get_signal_val(p_signal->vec_p_data[0], p_signal->data_type);
// cJSON_AddItemToObject(item, "val", cJSON_CreateString(val.c_str()));
cJSON_AddItemToObject(item, "ctrl_type", cJSON_CreateNumber(p_signal->ctrl_type));
if(p_signal->p_param)
{
@ -708,7 +704,6 @@ void ws_task()
cJSON_AddItemToObject(item, "max", cJSON_CreateString(std::to_string(p_signal->p_param->max).c_str()));
cJSON_AddItemToObject(item, "step", cJSON_CreateString(std::to_string(p_signal->p_param->step).c_str()));
cJSON_AddItemToObject(item, "unit", cJSON_CreateString(p_signal->p_param->unit.c_str()));
// cJSON_AddItemToObject(item, "default", cJSON_CreateString(p_signal->p_param->default_value.c_str()));
}
for(uint32_t j = 0; j < p_signal->vec_p_data.size(); j++)

View File

@ -29,7 +29,7 @@
<Item no="1" type="13" ctlModel="4" saddr="iec61850m.prj.ao.1" desc="参数02" LDev="PROT" LNode="LPHD1" DoName="DeviceName" fc="2" min="" max="" step="" unit="" value="1" default="1"/>
</Ao>
<Param desc="定值">
<Item no="0" type="5" ctlModel="4" saddr="iec61850m.prj.param.0" desc="定值01" LDev="PROT" LNode="LPHD1" DoName="SettingGrp" fc="2" min="0.05" max="150" step="0.001" unit="A" num="2">
<Item no="0" type="5" ctlModel="4" saddr="iec61850m.prj.param.0" desc="定值01" LDev="PROT" LNode="PTOC1" DoName="StrVal.setMag.f" fc="2" min="0.05" max="150" step="0.001" unit="A" num="2">
<SubItem value="15" default="15"/>
<SubItem value="27" default="27"/>
</Item>