deleted 101/104
This commit is contained in:
parent
a15ddd6b75
commit
b497f4cbdb
File diff suppressed because it is too large
Load Diff
@ -1,474 +0,0 @@
|
||||
#ifndef _ZJD_SUB_GDW104_PROCESS_H_
|
||||
#define _ZJD_SUB_GDW104_PROCESS_H_
|
||||
|
||||
#include "iec104.h"
|
||||
#include "sqlite/KompexSQLitePrerequisites.h"
|
||||
#include "sqlite/KompexSQLiteDatabase.h"
|
||||
#include "sqlite/KompexSQLiteStatement.h"
|
||||
#include "sqlite/KompexSQLiteException.h"
|
||||
#include "sqlite/KompexSQLiteStreamRedirection.h"
|
||||
#include "sqlite/KompexSQLiteBlob.h"
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string>
|
||||
|
||||
using namespace Kompex;
|
||||
|
||||
#define FILE_PATH_LEN 64
|
||||
#define MAX_FILEDATA_LEN 200
|
||||
#define EPS 1e-7
|
||||
#pragma pack(1)
|
||||
typedef struct
|
||||
{
|
||||
struIEC104Option iec104;
|
||||
char soeDir[FILE_PATH_LEN];
|
||||
char coDir[FILE_PATH_LEN];
|
||||
char fixptDir[FILE_PATH_LEN];
|
||||
char exvDir[FILE_PATH_LEN];
|
||||
char frzDir[FILE_PATH_LEN];
|
||||
char flowrevDir[FILE_PATH_LEN];
|
||||
char ulogDir[FILE_PATH_LEN];
|
||||
} struGDW104Option;
|
||||
#pragma pack()
|
||||
|
||||
typedef struct
|
||||
{
|
||||
time_t datetime;
|
||||
float fMaxVal;
|
||||
float fMinVal;
|
||||
float fCoef;
|
||||
float fBase;
|
||||
int iMaxVal;
|
||||
int iMinVal;
|
||||
int MaxTime;
|
||||
int MinTime;
|
||||
int iCurVal;
|
||||
} STRUCT_YCEXTREMUM;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
time_t datetime;
|
||||
float fCoef;
|
||||
float fBase;
|
||||
float fCurVal;
|
||||
int iCurVal;
|
||||
} STRUCT_FMRECORD;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int count;
|
||||
std::string ss_outmax;
|
||||
std::string ss_outmin;
|
||||
} STRUCT_FILEBUFFER;
|
||||
#if 1
|
||||
|
||||
#define CMD_GET_SOE_INFO 1
|
||||
#define CMD_GET_CO_INFO (1 << 1)
|
||||
#define CMD_GET_EXV_INFO (1 << 2)
|
||||
#define CMD_GET_FIXPT_INFO (1 << 3)
|
||||
#define CMD_GET_FRZ_INFO (1 << 4)
|
||||
#define CMD_GET_FLOWREV_INFO (1 << 5)
|
||||
#define CMD_GET_ULOG_INFO (1 << 6)
|
||||
#define CMD_GET_FILE_INFO (1 << 7)
|
||||
#define CMD_READ_FILE (1 << 8)
|
||||
#define CMD_GET_DIR_INFO (1 << 9)
|
||||
|
||||
#define FIOCMD_IDLE 0
|
||||
#define FIOCMD_CREATE_FILE 1
|
||||
#define FIOCMD_OPEN_FILE 2
|
||||
#define FIOCMD_GET_FILEINFO 3
|
||||
#define FIOCMD_DEL_FILE 4
|
||||
#define FIOCMD_MAKE_DIR 5
|
||||
#define FIOCMD_REMOVE_DIR 6
|
||||
#define FIOCMD_OPEN_DIR 7
|
||||
#define FIOCMD_READ_FILE 8
|
||||
#define FIOCMD_WRITE_FILE 9
|
||||
#define FIOCMD_READ_DIR 10
|
||||
#define FIOCMD_CLOSE_FILE 11
|
||||
#define FIOCMD_CLOSE_DIR 12
|
||||
|
||||
#define FIOCMD_VALID 0x7fffffff
|
||||
#define CMD_EXEC_ERR 0x80000000
|
||||
|
||||
typedef struct
|
||||
{
|
||||
std::string st_name;
|
||||
struct stat st_st;
|
||||
} struFileStat;
|
||||
|
||||
typedef std::vector<struFileStat> vecFileStat;
|
||||
class CGDW104FileProcess
|
||||
{
|
||||
private:
|
||||
DWORD last_sec;
|
||||
int m_uid;
|
||||
int m_information_address_length;
|
||||
int m_yx_information_address_start;
|
||||
int m_yc_information_address_start;
|
||||
int m_ym_information_address_start;
|
||||
|
||||
SQLiteDatabase m_database;
|
||||
struUnitStatic m_unit;
|
||||
|
||||
FILE* m_pFileHandle;
|
||||
BYTE m_fileBuffer[256];
|
||||
LONG m_nFilePos;
|
||||
LONG m_nFileLength;
|
||||
LONG m_nReadLen;
|
||||
|
||||
public:
|
||||
CGDW104FileProcess()
|
||||
{
|
||||
m_pFileHandle = NULL;
|
||||
m_nFilePos = 0;
|
||||
m_nReadLen = 0;
|
||||
m_nFileLength = 0;
|
||||
m_nCmdID = 0;
|
||||
m_bWr = FALSE;
|
||||
m_soe_save = 0;
|
||||
m_soe_load = 0;
|
||||
m_yklog_save = 0;
|
||||
m_yklog_load = 0;
|
||||
m_uid = -1;
|
||||
m_bCallAllFile = FALSE;
|
||||
last_sec = 0;
|
||||
m_last_day = -1;
|
||||
m_nCmdIDConfirm = 0;
|
||||
m_information_address_length = 3;
|
||||
m_yx_information_address_start = IEC_101_104_YX_START_ADDR;
|
||||
m_yc_information_address_start = IEC_101_104_YC_START_ADDR;
|
||||
m_ym_information_address_start = IEC_101_104_YM_START_ADDR;
|
||||
};
|
||||
virtual ~CGDW104FileProcess()
|
||||
{
|
||||
SaveMapToFile();
|
||||
if (m_pUnitYM)
|
||||
{
|
||||
delete [] m_pUnitYM;
|
||||
m_pUnitYM = NULL;
|
||||
}
|
||||
m_database.SaveDatabaseFromMemoryToFile("./gdw104.db");
|
||||
fprintf(stderr, "SaveDatabaseFromMemoryToFile finished.\n");
|
||||
if (m_pFileHandle)
|
||||
{
|
||||
fclose(m_pFileHandle);
|
||||
m_pFileHandle = NULL;
|
||||
}
|
||||
};
|
||||
BOOLEAN OnCreate(int, const void*, const void*);
|
||||
BOOLEAN OnTimer(void);
|
||||
|
||||
private:
|
||||
struSOE m_soes[DATABASE_SOE_NUM];
|
||||
int m_soe_save;
|
||||
int m_soe_load;
|
||||
struYKLog m_yklogs[DATABASE_YK_LOG_NUM];
|
||||
int m_yklog_save;
|
||||
int m_yklog_load;
|
||||
|
||||
BOOLEAN m_bWr;
|
||||
DWORD m_nCmdID;
|
||||
DWORD m_nCmdIDConfirm;
|
||||
|
||||
std::string m_pathName;
|
||||
vecFileStat m_vecFileStat;
|
||||
|
||||
std::string str_SOERecordDir;
|
||||
std::string str_coRecordDir;
|
||||
std::string str_exvRecordDir;
|
||||
std::string str_fixptRecordDir;
|
||||
std::string str_frzRecordDir;
|
||||
std::string str_flowrevRecordDir;
|
||||
std::string str_ulogRecordDir;
|
||||
|
||||
BOOLEAN m_bCallAllFile;
|
||||
time_t m_start_time;
|
||||
time_t m_end_time;
|
||||
|
||||
WORD m_last_day;
|
||||
|
||||
struUnitYM *m_pUnitYM;
|
||||
LONG m_total_ym;
|
||||
std::map<int, STRUCT_YCEXTREMUM> mapYcExetremumRecordDatas;
|
||||
std::map<int, STRUCT_FMRECORD> mapFmHisRecordDatas;
|
||||
|
||||
BOOLEAN SaveMapToFile(void);
|
||||
BOOLEAN LoadMapFromFile(int);
|
||||
BYTE GetCheckSum8(BYTE* pData, int count);
|
||||
int ReadDir(const char* pathName)
|
||||
{
|
||||
DIR *dir; // 定义目录指针
|
||||
struct dirent *dir_info; // 定义目录结构体
|
||||
m_vecFileStat.clear();
|
||||
char buf[260]; // 用于存放文件路径
|
||||
struFileStat filestat;
|
||||
if ((dir = opendir(pathName)) == NULL)
|
||||
{ // 打开目录
|
||||
vLog(LOG_ERROR, "打开文件目录:%s失败<%d,%s>\n", pathName, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
while ((dir_info = readdir(dir)) != NULL)
|
||||
{ // 读取目录下文件列表
|
||||
if (dir_info->d_name[0] == '.')
|
||||
{ // 过滤掉 '.' 和 '..'
|
||||
continue;
|
||||
}
|
||||
// 获取文件全路径,并打印
|
||||
sprintf(buf, "%s/%s", pathName, dir_info->d_name);
|
||||
//获取文件属性
|
||||
if (stat(buf, &filestat.st_st) != 0)
|
||||
{
|
||||
vLog(LOG_ERROR, "获取文件%s属性失败<%d,%s>\n", buf, errno, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
filestat.st_name = buf;
|
||||
m_vecFileStat.push_back(filestat);
|
||||
}
|
||||
closedir(dir); // 关闭目录
|
||||
return m_vecFileStat.size();
|
||||
}
|
||||
|
||||
int mkLogDir(const char* pathName)
|
||||
{
|
||||
if (access(pathName, F_OK) == 0) return 0;
|
||||
// 创建目录
|
||||
if (mkdir(pathName, 0777) == -1)
|
||||
{
|
||||
vLog(LOG_ERROR, "创建文件夹 %s失败<%d,%s>\r\n", pathName, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
void delete_files_in_dir(const char*);
|
||||
void DumpSOE(void);
|
||||
void DumpYKLog(void);
|
||||
void UpdateExtremumRecord(BOOLEAN);
|
||||
void DumpYCHisRecord(LONG);
|
||||
void DumpFmHisRecord(LONG);
|
||||
|
||||
void createSOEFile(void);
|
||||
void createYKLogFile(void);
|
||||
void createExtremumRecordFile(void);
|
||||
void createYCHisRecordFile(void);
|
||||
void createFmHisRecordFile(void);
|
||||
public:
|
||||
void AddFmRecord(struUnitYM* yms, int count)
|
||||
{
|
||||
memcpy(m_pUnitYM, yms, sizeof(struUnitYM) * count);
|
||||
}
|
||||
void AddExtremumRecord(int point, LONG value)
|
||||
{
|
||||
if (mapYcExetremumRecordDatas.find(point) == mapYcExetremumRecordDatas.end()) return;
|
||||
LONG maxVal = mapYcExetremumRecordDatas[point].iMaxVal;
|
||||
LONG minVal = mapYcExetremumRecordDatas[point].iMinVal;
|
||||
if (value > maxVal)
|
||||
{
|
||||
mapYcExetremumRecordDatas[point].fMaxVal = value * mapYcExetremumRecordDatas[point].fCoef + mapYcExetremumRecordDatas[point].fBase;
|
||||
mapYcExetremumRecordDatas[point].iMaxVal = value;
|
||||
mapYcExetremumRecordDatas[point].MaxTime = system32.timers;
|
||||
}
|
||||
if (value < minVal)
|
||||
{
|
||||
mapYcExetremumRecordDatas[point].fMinVal = value * mapYcExetremumRecordDatas[point].fCoef + mapYcExetremumRecordDatas[point].fBase;
|
||||
mapYcExetremumRecordDatas[point].iMinVal = value;
|
||||
mapYcExetremumRecordDatas[point].MinTime = system32.timers;
|
||||
}
|
||||
mapYcExetremumRecordDatas[point].iCurVal = value;
|
||||
}
|
||||
void PushSOE(unionCP56Time& st, int order, BOOLEAN value, BYTE qds, int uid = -1, int point = -1)
|
||||
{
|
||||
m_soes[m_soe_save].st.year = st.year;
|
||||
m_soes[m_soe_save].st.month = st.month;
|
||||
m_soes[m_soe_save].st.dayofmonth = st.dayofmonth;
|
||||
m_soes[m_soe_save].st.dayofweek = st.dayofweek;
|
||||
m_soes[m_soe_save].st.hour = st.hour;
|
||||
m_soes[m_soe_save].st.minute = st.minute;
|
||||
m_soes[m_soe_save].st.millisecond = st.millisecond;
|
||||
if (order < 0 || order >= DATABASE_YX_NUM)
|
||||
{
|
||||
m_soes[m_soe_save].order = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_soes[m_soe_save].order = order;
|
||||
}
|
||||
m_soes[m_soe_save].value = value;
|
||||
m_soes[m_soe_save].uid = uid;
|
||||
m_soes[m_soe_save].point = point;
|
||||
m_soes[m_soe_save].qds = qds;
|
||||
m_soe_save++;
|
||||
m_soe_save = m_soe_save % DATABASE_SOE_NUM;
|
||||
}
|
||||
|
||||
void PushYKLog(unionCP56Time& st, int point, BOOLEAN value, BYTE type, BYTE source = -1, int uid = -1)
|
||||
{
|
||||
m_yklogs[m_yklog_save].st.year = st.year;
|
||||
m_yklogs[m_yklog_save].st.month = st.month;
|
||||
m_yklogs[m_yklog_save].st.dayofmonth = st.dayofmonth;
|
||||
m_yklogs[m_yklog_save].st.dayofweek = st.dayofweek;
|
||||
m_yklogs[m_yklog_save].st.hour = st.hour;
|
||||
m_yklogs[m_yklog_save].st.minute = st.minute;
|
||||
m_yklogs[m_yklog_save].st.millisecond = st.millisecond;
|
||||
m_yklogs[m_yklog_save].point = point;
|
||||
m_yklogs[m_yklog_save].value = value;
|
||||
m_yklogs[m_yklog_save].type = type;
|
||||
m_yklogs[m_yklog_save].source = source;
|
||||
m_yklogs[m_yklog_save].uid = uid;
|
||||
m_yklog_save++;
|
||||
m_yklog_save = m_yklog_save % DATABASE_YK_LOG_NUM;
|
||||
}
|
||||
|
||||
void ReadDir(const char* dirName, BOOLEAN callAllFile, unionCP56Time st, unionCP56Time et)
|
||||
{
|
||||
m_nCmdID = FIOCMD_READ_DIR;
|
||||
m_pathName = dirName;
|
||||
m_bCallAllFile = callAllFile;
|
||||
m_start_time = unionCP56TimetoTime_t(&st);
|
||||
m_end_time = unionCP56TimetoTime_t(&et);
|
||||
}
|
||||
|
||||
void OpenFile(const char* filename, bool bWr = FALSE)
|
||||
{
|
||||
m_nCmdID = FIOCMD_OPEN_FILE;
|
||||
m_pathName = filename;
|
||||
m_bWr = bWr;
|
||||
}
|
||||
void CloseFile()
|
||||
{
|
||||
m_nCmdID = FIOCMD_CLOSE_FILE;
|
||||
}
|
||||
void ReadFile()
|
||||
{
|
||||
m_nCmdID = FIOCMD_READ_FILE;
|
||||
}
|
||||
DWORD getCMD(void)
|
||||
{
|
||||
DWORD result = m_nCmdIDConfirm;
|
||||
m_nCmdIDConfirm = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
int FileData(BYTE* pData)
|
||||
{
|
||||
ValToBuf(pData, m_nFilePos, 4); pData+= 4;
|
||||
if (FileLeftLength() <= 0)
|
||||
{
|
||||
*pData = 0; pData++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pData = 1; pData++;
|
||||
ReadFile();
|
||||
}
|
||||
memcpy(pData, m_fileBuffer, m_nReadLen); pData += m_nReadLen;
|
||||
*pData = GetCheckSum8(m_fileBuffer, m_nReadLen);
|
||||
m_nFilePos += m_nReadLen;
|
||||
return (m_nReadLen + 6);
|
||||
}
|
||||
LONG FilePos(void) const
|
||||
{
|
||||
return m_nFilePos;
|
||||
}
|
||||
LONG FileLeftLength(void) const
|
||||
{
|
||||
return (m_nFileLength - m_nFilePos);
|
||||
}
|
||||
int FileCount(void) const
|
||||
{
|
||||
return m_vecFileStat.size();
|
||||
}
|
||||
std::string FileName(int order) const
|
||||
{
|
||||
if (order >= (int)m_vecFileStat.size()) return NULL;
|
||||
return m_vecFileStat[order].st_name;
|
||||
}
|
||||
LONG FileLength(int order) const
|
||||
{
|
||||
if (order >= (int)m_vecFileStat.size()) return -1;
|
||||
return m_vecFileStat[order].st_st.st_size;
|
||||
}
|
||||
time_t FileTime(int order) const
|
||||
{
|
||||
if (order >= (int)m_vecFileStat.size()) return -1;
|
||||
return m_vecFileStat[order].st_st.st_atime;
|
||||
}
|
||||
LONG FileLength(std::string name) const
|
||||
{
|
||||
for (int i = 0; i < (int)m_vecFileStat.size(); i++)
|
||||
{
|
||||
if (name == m_vecFileStat[i].st_name)
|
||||
{
|
||||
return m_vecFileStat[i].st_st.st_size;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
time_t FileTime(std::string name) const
|
||||
{
|
||||
for (int i = 0; i < (int)m_vecFileStat.size(); i++)
|
||||
{
|
||||
if (name == m_vecFileStat[i].st_name)
|
||||
{
|
||||
return m_vecFileStat[i].st_st.st_atime;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char dirname[FILE_PATH_LEN];
|
||||
char filename[FILE_PATH_LEN];
|
||||
LONG loadptr;
|
||||
DWORD dirID;
|
||||
DWORD length;
|
||||
BOOLEAN allfile;
|
||||
BYTE ret_val;
|
||||
} stCallFileDir;
|
||||
|
||||
class CSubGDW104Process : public CIEC104Process
|
||||
{
|
||||
private:
|
||||
CGDW104FileProcess m_gdwFile;
|
||||
struGDW104Option gdw_option;
|
||||
DWORD m_dwFileType;
|
||||
stCallFileDir m_FileDir;
|
||||
|
||||
public:
|
||||
CSubGDW104Process();
|
||||
virtual ~CSubGDW104Process();
|
||||
|
||||
BOOLEAN OnPreCreate(int);
|
||||
BOOLEAN OnCreated(int);
|
||||
BOOLEAN Run(void);
|
||||
BOOLEAN OnTimer(void);
|
||||
BOOLEAN FetchUnitYC(int);
|
||||
BOOLEAN FetchUnitYM(int);
|
||||
public:
|
||||
void GetItemEvents(CIEC104ProcessItem*);
|
||||
public:
|
||||
int MakeYKFrame(CIEC104ProcessItem*, int);
|
||||
int MakeYTFrame(CIEC104ProcessItem*, int);
|
||||
int MakeFileFrame(CIEC104ProcessItem*, int);
|
||||
|
||||
BOOLEAN OnUFrameReceived(BOOLEAN, BOOLEAN, BOOLEAN, BOOLEAN, BOOLEAN, BOOLEAN, int);
|
||||
BOOLEAN OnIFrameReceived(WORD, WORD, BYTE*, int, int);
|
||||
|
||||
int Receive_Single_command(CIEC104ProcessItem*, const BYTE*, BYTE, BYTE*, int&); //单点令
|
||||
int Receive_Double_command(CIEC104ProcessItem*, const BYTE*, BYTE, BYTE*, int&); //单点令
|
||||
int Receive_Set_point_command_normalized(CIEC104ProcessItem*, const BYTE*, BYTE, BYTE*, int&); //设定规一化值命令
|
||||
int Receive_Set_point_command_scaled(CIEC104ProcessItem*, const BYTE*, BYTE, BYTE*, int&); //设定标度化值命令
|
||||
int Receive_Set_point_command_short_floating(CIEC104ProcessItem*, const BYTE*, BYTE, BYTE*, int&); //设定短浮点值命令
|
||||
int Receive_FileTrans(CIEC104ProcessItem*, const BYTE*, BYTE); //读取文件
|
||||
BOOLEAN parseFileReadDirAct(CIEC104ProcessItem*, const BYTE*);
|
||||
BOOLEAN parseFileReadFileSelAct(CIEC104ProcessItem*, const BYTE*);
|
||||
BOOLEAN parseFileReadFileDataCon(CIEC104ProcessItem*, const BYTE*);
|
||||
int Send_CallFileDir_Confirm(CIEC104ProcessItem*, DWORD, int);
|
||||
int Send_FileDir(CIEC104ProcessItem*, BOOLEAN, BOOLEAN, int, int, int);
|
||||
int Send_CallFileSel_Confirm(CIEC104ProcessItem*, DWORD, int);
|
||||
int Send_CallFileDat_Ack(CIEC104ProcessItem*, DWORD, int);
|
||||
};
|
||||
|
||||
#endif //_ZJD_SUB_GDW104_PROCESS_H_
|
@ -1,241 +0,0 @@
|
||||
#include "sub_iec101_balanced.h"
|
||||
|
||||
|
||||
/***************************************************************************************/
|
||||
BOOLEAN CIEC101SecondaryBalancedProcess::OnPreCreate(int id)
|
||||
{
|
||||
if (!CIEC101Process::OnPreCreate(id)) return FALSE;
|
||||
|
||||
int i;
|
||||
int uid;
|
||||
CIEC101SecondaryBalancedProcessItem* pItem;
|
||||
for (i = 0; i < PROCESS_UNIT_NUM; i++)
|
||||
{
|
||||
pItem = (CIEC101SecondaryBalancedProcessItem *)GetItem(i);
|
||||
if (NULL == pItem) continue;
|
||||
uid = pItem->GetUnitID();
|
||||
if (uid < 0 || uid >= UNIT_NUM) continue;
|
||||
BYTE phy_addr[2];
|
||||
GetUnitAddr(uid, phy_addr, 2);
|
||||
pItem->Attach(uid, phy_addr[0], phy_addr[0], m_option.originatorAddress); //默认公共地址和物理地址一致
|
||||
pItem->setAppLayerParameters(m_option.sizeOfCOT, m_option.sizeOfCA, m_option.sizeOfIOA, m_option.maxSizeOfASDU);
|
||||
|
||||
Slave_setLinkLayerAddressOtherStation(pItem, phy_addr[1]);
|
||||
|
||||
pItem->setAppLayerIOABase();
|
||||
pItem->setAppLayerDataCount(GetUnitYXCount(uid), GetUnitYCCount(uid), GetUnitYMCount(uid));
|
||||
}
|
||||
|
||||
last_sec != (time_t)system32.timers;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN CIEC101SecondaryBalancedProcess::Run(void)
|
||||
{
|
||||
if (!CIEC101Process::Run()) return FALSE;
|
||||
|
||||
FeedDog();
|
||||
CIEC101ProcessItem* pItem = (CIEC101ProcessItem *)GetCurItem();
|
||||
LinkLayerPrimaryBalanced_runStateMachine(pItem);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN CIEC101SecondaryBalancedProcess::OnTimer(void)
|
||||
{
|
||||
if (!CIEC101Process::OnTimer()) return FALSE;
|
||||
|
||||
BOOLEAN sec_changed = FALSE;
|
||||
if (last_sec != (time_t)system32.timers)
|
||||
{
|
||||
last_sec = (time_t)system32.timers;
|
||||
sec_changed = TRUE;
|
||||
}
|
||||
|
||||
CIEC101ProcessItem* pItem = (CIEC101ProcessItem *)GetCurItem();
|
||||
if (NULL == pItem) return TRUE;
|
||||
int uid = pItem->GetUnitID();
|
||||
if (uid < 0 || uid >= UNIT_NUM) return TRUE;
|
||||
|
||||
//刷新事件记录库
|
||||
GetItemEvents(pItem);
|
||||
//刷新遥测库
|
||||
FetchUnitYC(0);
|
||||
|
||||
if (pItem->interrogation_finish)
|
||||
{
|
||||
//总召唤结束,开始上送遥信变位
|
||||
GetItemYXBWs(pItem);
|
||||
//总召唤结束,开始刷新遥测变位缓冲。
|
||||
if (pItem->ycbws.count <= 0)
|
||||
{ //当遥测变位发送结束后才更新
|
||||
GetItemYCBWs(pItem);
|
||||
}
|
||||
//发送遥控返校
|
||||
if (MakeYKFrame(pItem)) return TRUE;
|
||||
if (MakeYTFrame(pItem)) return TRUE;
|
||||
if (Send_Single_point_information(pItem)) return TRUE;
|
||||
if (Send_Single_point_information_with_time_tag_cp56time2a(pItem)) return TRUE;
|
||||
if (!pItem->interrogation_start)
|
||||
{ //变位遥测优先级在总召唤之后。
|
||||
if (sec_changed)
|
||||
{
|
||||
switch (m_option.yc_type)
|
||||
{
|
||||
case USE_YC_NB: //标度化值
|
||||
return Send_Measured_value_scaled(pItem);
|
||||
case USE_YC_NC: //短浮点数
|
||||
return Send_Measured_value_short_floating_point(pItem);
|
||||
case USE_YC_ND: //不带品质归一化值
|
||||
return Send_Measured_value_normalised_without_quality(pItem);
|
||||
default: //USE_YC_NA: 归一化值
|
||||
return Send_Measured_value_normalised(pItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//响应总召唤命令
|
||||
if (pItem->interrogation_start)
|
||||
{
|
||||
if (pItem->call_type != IEC_101_104_COT_INTERROGATION)
|
||||
{ //组召唤
|
||||
//激活终止
|
||||
Send_FrameInterrogation(pItem);
|
||||
pItem->call_type = 0;
|
||||
pItem->interrogation_finish = TRUE;
|
||||
pItem->interrogation_start = FALSE;
|
||||
pItem->interrogation_yx_fin = TRUE;
|
||||
pItem->interrogation_yc_fin = TRUE;
|
||||
}
|
||||
else if (!pItem->interrogation_yx_fin)
|
||||
{
|
||||
Send_Single_point_information(pItem, IEC_101_104_COT_INTERROGATION);
|
||||
}
|
||||
else if (!pItem->interrogation_yc_fin)
|
||||
{
|
||||
switch (m_option.yc_type)
|
||||
{
|
||||
case USE_YC_NB: //标度化值
|
||||
return Send_Measured_value_scaled(pItem, IEC_101_104_COT_INTERROGATION);
|
||||
case USE_YC_NC: //短浮点数
|
||||
return Send_Measured_value_short_floating_point(pItem, IEC_101_104_COT_INTERROGATION);
|
||||
case USE_YC_ND: //不带品质归一化值
|
||||
return Send_Measured_value_normalised_without_quality(pItem, IEC_101_104_COT_INTERROGATION);
|
||||
default: //USE_YC_NA: 归一化值
|
||||
return Send_Measured_value_normalised(pItem, IEC_101_104_COT_INTERROGATION);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Send_FrameInterrogation(pItem);
|
||||
pItem->call_type = 0;
|
||||
pItem->interrogation_finish = TRUE;
|
||||
pItem->interrogation_start = FALSE;
|
||||
pItem->interrogation_yx_fin = TRUE;
|
||||
pItem->interrogation_yc_fin = TRUE;
|
||||
}
|
||||
}
|
||||
else if (pItem->pulse_start)
|
||||
{
|
||||
if (!pItem->pulse_fin)
|
||||
{
|
||||
Send_Integrated_totals(pItem, IEC_101_104_COT_REQCOGEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
Send_FrameCounterInterrogation(pItem);
|
||||
pItem->call_type = 0;
|
||||
pItem->pulse_start = FALSE;
|
||||
pItem->pulse_fin = TRUE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//平衡方式从协议接收到主站报文
|
||||
void CIEC101SecondaryBalancedProcess::LinkLayerSecondaryBalanced_ReceivedMessage(BYTE fc, BOOLEAN isBroadcast, BOOLEAN fcb, BOOLEAN fcv, int address, BYTE* msg, int userDataStart, int userDataLength)
|
||||
{
|
||||
CIEC101ProcessItem* pItem;
|
||||
if (address == -1) pItem = (CIEC101ProcessItem *)GetCurItem();
|
||||
else
|
||||
{
|
||||
int uid = GetUnitByAddr((BYTE *)&address, m_linkLayer.linkLayerParameters.addressLength);
|
||||
if (uid < 0 || uid >= UNIT_NUM) return;
|
||||
pItem = (CIEC101ProcessItem *)GetItem(GetOrderByUnitID(uid));
|
||||
|
||||
UnitFeedDog(uid);
|
||||
}
|
||||
if (pItem == NULL)
|
||||
{
|
||||
vLog(LOG_DEBUG, "PLL RECV - response from unknown slave %i\n", address);
|
||||
return;
|
||||
}
|
||||
|
||||
pIEC101_LinkLayerSecondaryBalanced self = &(pItem->secondaryLinkBalanced);
|
||||
if (fcv)
|
||||
{
|
||||
if (LinkLayerSecondaryBalanced_checkFCB(self, fcb) == FALSE) return;
|
||||
}
|
||||
switch (fc)
|
||||
{
|
||||
case LL_FC_00_RESET_REMOTE_LINK:
|
||||
//vLog(LOG_DEBUG, "SLL - RECV FC 00 - RESET REMOTE LINK\n");
|
||||
self->expectedFcb = TRUE;
|
||||
//vLog(LOG_DEBUG, "SLL - SEND FC 00 - ACK\n");
|
||||
if (m_linkLayer.linkLayerParameters.useSingleCharACK)
|
||||
{
|
||||
SendSingleCharCharacter();
|
||||
}
|
||||
else
|
||||
{
|
||||
SendFixedFrame(LL_FC_00_ACK, pItem->address, FALSE, m_linkLayer.dir, FALSE, FALSE);
|
||||
}
|
||||
break;
|
||||
case LL_FC_02_TEST_FUNCTION_FOR_LINK:
|
||||
//vLog(LOG_DEBUG, "SLL - RECV FC 02 - TEST FUNCTION FOR LINK\n");
|
||||
//vLog(LOG_DEBUG, "SLL - SEND FC 00 - ACK\n");
|
||||
if (m_linkLayer.linkLayerParameters.useSingleCharACK)
|
||||
{
|
||||
SendSingleCharCharacter();
|
||||
}
|
||||
else
|
||||
{
|
||||
SendFixedFrame(LL_FC_00_ACK, pItem->address, FALSE, m_linkLayer.dir, FALSE, FALSE);
|
||||
}
|
||||
break;
|
||||
case LL_FC_03_USER_DATA_CONFIRMED:
|
||||
//vLog(LOG_DEBUG, "SLL - RECV FC 03 - USER DATA CONFIRMED\n");
|
||||
if (userDataLength > 0)
|
||||
{
|
||||
if (ApplicationLayer_ReceivedData(pItem, msg, isBroadcast, userDataStart, userDataLength))
|
||||
{
|
||||
//vLog(LOG_DEBUG, "SLL - SEND FC 00 - ACK\n");
|
||||
if (m_linkLayer.linkLayerParameters.useSingleCharACK)
|
||||
{
|
||||
SendSingleCharCharacter();
|
||||
}
|
||||
else
|
||||
{
|
||||
SendFixedFrame(LL_FC_00_ACK, pItem->address, FALSE, m_linkLayer.dir, FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LL_FC_04_USER_DATA_NO_REPLY:
|
||||
//vLog(LOG_DEBUG, "SLL -FC 04 - USER DATA NO REPLY\n");
|
||||
if (userDataLength > 0)
|
||||
{
|
||||
ApplicationLayer_ReceivedData(pItem, msg, isBroadcast, userDataStart, userDataLength);
|
||||
}
|
||||
break;
|
||||
case LL_FC_09_REQUEST_LINK_STATUS:
|
||||
//vLog(LOG_DEBUG, "SLL - RECV FC 09 - REQUEST LINK STATUS");
|
||||
//vLog(LOG_DEBUG, "SLL - SEND FC 11 - STATUS OF LINK\n");
|
||||
SendFixedFrame(LL_FC_11_STATUS_OF_LINK_OR_ACCESS_DEMAND, pItem->address, FALSE, m_linkLayer.dir, FALSE, FALSE);
|
||||
break;
|
||||
default:
|
||||
//vLog(LOG_DEBUG, "SLL - UNEXPECTED LINK LAYER MESSAGE");
|
||||
//vLog(LOG_DEBUG, "SLL - SEND FC 15 - SERVICE NOT IMPLEMENTED\n");
|
||||
SendFixedFrame(LL_FC_15_SERVICE_NOT_IMPLEMENTED, pItem->address, FALSE, m_linkLayer.dir, FALSE, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
#ifndef _ZJD_SUB_IEC101_BALANCED_PROCESS_H_
|
||||
#define _ZJD_SUB_IEC101_BALANCED_PROCESS_H_
|
||||
|
||||
#include "iec101.h"
|
||||
|
||||
class CIEC101SecondaryBalancedProcessItem : public CIEC101ProcessItem
|
||||
{
|
||||
public:
|
||||
CIEC101SecondaryBalancedProcessItem() {};
|
||||
virtual ~CIEC101SecondaryBalancedProcessItem() {};
|
||||
public:
|
||||
void Attach(int uid, int physicsAddress = 0, int commonAddress = 0, int originatorAddress = 0)
|
||||
{
|
||||
CIEC101ProcessItem::Attach(uid, physicsAddress, commonAddress, m_originatorAddress);
|
||||
primaryLinkBalanced.otherStationAddress = physicsAddress;
|
||||
common_address = commonAddress;
|
||||
applicationlParameters.originatorAddress = originatorAddress;
|
||||
}
|
||||
void setAppLayerDataCount(int yx = 0, int yc = 0, int ym = 0)
|
||||
{
|
||||
total_yx = yx;
|
||||
total_yc = yc;
|
||||
total_ym = ym;
|
||||
yx_pos = 0;
|
||||
yc_pos = 0;
|
||||
ym_pos = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class CIEC101SecondaryBalancedProcess : public CIEC101SecondaryProcess
|
||||
{
|
||||
public:
|
||||
CIEC101SecondaryBalancedProcess() {m_linkLayer.mode = llSecBalanced;};
|
||||
virtual ~CIEC101SecondaryBalancedProcess() {};
|
||||
BOOLEAN OnPreCreate(int id);
|
||||
BOOLEAN Run(void);
|
||||
BOOLEAN OnTimer(void);
|
||||
|
||||
CIEC101ProcessItem *CreateItem(int ord)
|
||||
{
|
||||
return dynamic_cast<CIEC101ProcessItem *>(new CIEC101SecondaryBalancedProcessItem);
|
||||
}
|
||||
|
||||
void Slave_setLinkLayerAddressOtherStation(CIEC101ProcessItem* pItem, int address)
|
||||
{
|
||||
pItem->address = address;
|
||||
}
|
||||
private:
|
||||
BOOLEAN LinkLayerSecondaryBalanced_checkFCB(pIEC101_LinkLayerSecondaryBalanced self, BOOLEAN fcb)
|
||||
{
|
||||
if (fcb != self->expectedFcb)
|
||||
{
|
||||
//vLog(LOG_DEBUG, "ERROR: Frame count bit (FCB) invalid!\n");
|
||||
/* TODO change link status */
|
||||
return FALSE;
|
||||
}
|
||||
self->expectedFcb = !(self->expectedFcb);
|
||||
return TRUE;
|
||||
}
|
||||
virtual void LinkLayerSecondaryBalanced_ReceivedMessage(BYTE fc, BOOLEAN isBroadcast, BOOLEAN fcb, BOOLEAN fcv, int address, BYTE* msg, int userDataStart, int userDataLength);
|
||||
};
|
||||
|
||||
#endif // _ZJD_SUB_IEC101_BALANCED_PROCESS_H_
|
@ -1,404 +0,0 @@
|
||||
#include "sub_iec101_unbalanced.h"
|
||||
|
||||
|
||||
/***************************************************************************************/
|
||||
BOOLEAN CIEC101SecondaryUnbalancedProcess::OnPreCreate(int id)
|
||||
{
|
||||
if (!CIEC101Process::OnPreCreate(id)) return FALSE;
|
||||
|
||||
int i;
|
||||
int uid;
|
||||
CIEC101SecondaryUnbalancedProcessItem* pItem;
|
||||
for (i = 0; i < PROCESS_UNIT_NUM; i++)
|
||||
{
|
||||
pItem = (CIEC101SecondaryUnbalancedProcessItem *)GetItem(i);
|
||||
if (NULL == pItem) continue;
|
||||
uid = pItem->GetUnitID();
|
||||
if (uid < 0 || uid >= UNIT_NUM) continue;
|
||||
BYTE phy_addr[2];
|
||||
GetUnitAddr(uid, phy_addr, 2);
|
||||
pItem->Attach(uid, phy_addr[0], phy_addr[0], m_option.originatorAddress); //默认公共地址和物理地址一致
|
||||
pItem->setAppLayerParameters(m_option.sizeOfCOT, m_option.sizeOfCA, m_option.sizeOfIOA, m_option.maxSizeOfASDU);
|
||||
|
||||
Slave_setLinkLayerAddressOtherStation(pItem, phy_addr[1]);
|
||||
pItem->setAppLayerIOABase();
|
||||
pItem->setAppLayerDataCount(GetUnitYXCount(uid), GetUnitYCCount(uid), GetUnitYMCount(uid));
|
||||
}
|
||||
|
||||
last_sec = (time_t)system32.timers;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN CIEC101SecondaryUnbalancedProcess::Run(void)
|
||||
{
|
||||
if (!CIEC101Process::Run()) return FALSE;
|
||||
|
||||
FeedDog();
|
||||
|
||||
if (m_state != LL_STATE_IDLE)
|
||||
{
|
||||
if ((getTimeInMs() - m_lastReceivedMsg) > (unsigned int) m_idleTimeout)
|
||||
{
|
||||
llsu_setState(LL_STATE_IDLE);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN CIEC101SecondaryUnbalancedProcess::OnTimer(void)
|
||||
{
|
||||
if (!CIEC101Process::OnTimer()) return FALSE;
|
||||
|
||||
BOOLEAN sec_changed = FALSE;
|
||||
if (last_sec != (time_t)system32.timers)
|
||||
{
|
||||
last_sec = (time_t)system32.timers;
|
||||
sec_changed = TRUE;
|
||||
}
|
||||
|
||||
CIEC101ProcessItem* pItem = (CIEC101ProcessItem *)GetCurItem();
|
||||
if (NULL == pItem) return TRUE;
|
||||
int uid = pItem->GetUnitID();
|
||||
if (uid < 0 || uid >= UNIT_NUM) return TRUE;
|
||||
|
||||
//刷新事件记录库
|
||||
GetItemEvents(pItem);
|
||||
//刷新遥测库
|
||||
FetchUnitYC(0);
|
||||
|
||||
if (pItem->interrogation_finish)
|
||||
{
|
||||
//总召唤结束,开始上送遥信变位
|
||||
GetItemYXBWs(pItem);
|
||||
//总召唤结束,开始刷新遥测变位缓冲。
|
||||
if (pItem->ycbws.count <= 0)
|
||||
{ //当遥测变位发送结束后才更新
|
||||
GetItemYCBWs(pItem);
|
||||
}
|
||||
//发送遥控返校
|
||||
if (MakeYKFrame(pItem)) return TRUE;
|
||||
if (MakeYTFrame(pItem)) return TRUE;
|
||||
if (Send_Single_point_information(pItem)) return TRUE;
|
||||
if (Send_Single_point_information_with_time_tag_cp56time2a(pItem)) return TRUE;
|
||||
if (!pItem->interrogation_start)
|
||||
{ //变位遥测优先级在总召唤之后。
|
||||
if (sec_changed)
|
||||
{
|
||||
switch (m_option.yc_type)
|
||||
{
|
||||
case USE_YC_NB: //标度化值
|
||||
return Send_Measured_value_scaled(pItem);
|
||||
case USE_YC_NC: //短浮点数
|
||||
return Send_Measured_value_short_floating_point(pItem);
|
||||
case USE_YC_ND: //不带品质归一化值
|
||||
return Send_Measured_value_normalised_without_quality(pItem);
|
||||
default: //USE_YC_NA: 归一化值
|
||||
return Send_Measured_value_normalised(pItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//响应总召唤命令
|
||||
if (pItem->interrogation_start)
|
||||
{
|
||||
if (pItem->call_type != IEC_101_104_COT_INTERROGATION)
|
||||
{ //组召唤
|
||||
//激活终止
|
||||
Send_FrameInterrogation(pItem);
|
||||
pItem->call_type = 0;
|
||||
pItem->interrogation_finish = TRUE;
|
||||
pItem->interrogation_start = FALSE;
|
||||
pItem->interrogation_yx_fin = TRUE;
|
||||
pItem->interrogation_yc_fin = TRUE;
|
||||
}
|
||||
else if (!pItem->interrogation_yx_fin)
|
||||
{
|
||||
Send_Single_point_information(pItem, IEC_101_104_COT_INTERROGATION);
|
||||
}
|
||||
else if (!pItem->interrogation_yc_fin)
|
||||
{
|
||||
switch (m_option.yc_type)
|
||||
{
|
||||
case USE_YC_NB: //标度化值
|
||||
return Send_Measured_value_scaled(pItem, IEC_101_104_COT_INTERROGATION);
|
||||
case USE_YC_NC: //短浮点数
|
||||
return Send_Measured_value_short_floating_point(pItem, IEC_101_104_COT_INTERROGATION);
|
||||
case USE_YC_ND: //不带品质归一化值
|
||||
return Send_Measured_value_normalised_without_quality(pItem, IEC_101_104_COT_INTERROGATION);
|
||||
default: //USE_YC_NA: 归一化值
|
||||
return Send_Measured_value_normalised(pItem, IEC_101_104_COT_INTERROGATION);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Send_FrameInterrogation(pItem);
|
||||
pItem->call_type = 0;
|
||||
pItem->interrogation_finish = TRUE;
|
||||
pItem->interrogation_start = FALSE;
|
||||
pItem->interrogation_yx_fin = TRUE;
|
||||
pItem->interrogation_yc_fin = TRUE;
|
||||
}
|
||||
}
|
||||
else if (pItem->pulse_start)
|
||||
{
|
||||
if (!pItem->pulse_fin)
|
||||
{
|
||||
Send_Integrated_totals(pItem, IEC_101_104_COT_REQCOGEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
Send_FrameCounterInterrogation(pItem);
|
||||
pItem->call_type = 0;
|
||||
pItem->pulse_start = FALSE;
|
||||
pItem->pulse_fin = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int CIEC101SecondaryUnbalancedProcess::OnPackageReceived(BYTE* pBuf, int msgSize, int /* ord = -1 */)
|
||||
{
|
||||
m_lastReceivedMsg = getTimeInMs();
|
||||
|
||||
int userDataLength = 0;
|
||||
int userDataStart = 0;
|
||||
BYTE c;
|
||||
int csStart;
|
||||
int csIndex;
|
||||
int address = 0;
|
||||
int addressLength = m_linkLayer.linkLayerParameters.addressLength;
|
||||
BYTE* msg = (BYTE *)pBuf;
|
||||
|
||||
if (msg [0] == 0x68)
|
||||
{
|
||||
if (msg [1] != msg [2])
|
||||
{
|
||||
vLog(LOG_DEBUG, "ERROR: L fields differ!\n");
|
||||
llsu_setState(LL_STATE_ERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
userDataLength = (int)msg [1] - addressLength - 1;
|
||||
userDataStart = 5 + addressLength;
|
||||
csStart = 4;
|
||||
csIndex = userDataStart + userDataLength;
|
||||
/* check if message size is reasonable */
|
||||
if (msgSize != (userDataStart + userDataLength + 2 /* CS + END */))
|
||||
{
|
||||
vLog(LOG_DEBUG, "ERROR: Invalid message length\n");
|
||||
llsu_setState(LL_STATE_ERROR);
|
||||
return 1;
|
||||
}
|
||||
c = msg [4];
|
||||
}
|
||||
else if (msg [0] == 0x10)
|
||||
{
|
||||
c = msg [1];
|
||||
csStart = 1;
|
||||
csIndex = 2 + addressLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
vLog(LOG_DEBUG, "ERROR: Received unexpected message type in unbalanced slave mode!\n");
|
||||
llsu_setState(LL_STATE_ERROR);
|
||||
return 1;
|
||||
}
|
||||
BOOLEAN isBroadcast = false;
|
||||
CIEC101ProcessItem* pItem;
|
||||
/* check address */
|
||||
if (addressLength > 0)
|
||||
{
|
||||
address = msg[csStart + 1];
|
||||
if (addressLength > 1)
|
||||
{
|
||||
address += msg [csStart + 2] * 0x100;
|
||||
if (address == 65535) isBroadcast = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (address == 255) isBroadcast = TRUE;
|
||||
}
|
||||
}
|
||||
int fc = c & 0x0f;
|
||||
if (isBroadcast)
|
||||
{
|
||||
if (fc != LL_FC_04_USER_DATA_NO_REPLY)
|
||||
{
|
||||
vLog(LOG_DEBUG, "ERROR: Invalid function code for broadcast message!\n");
|
||||
llsu_setState(LL_STATE_ERROR);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int uid = GetUnitByAddr((BYTE *)&address, m_linkLayer.linkLayerParameters.addressLength);
|
||||
if (uid < 0 || uid >= UNIT_NUM)
|
||||
{
|
||||
vLog(LOG_DEBUG, "INFO: unknown link layer address(%i) -> ignore message\n", address);
|
||||
return 1;
|
||||
}
|
||||
pItem = (CIEC101ProcessItem *)GetItem(GetOrderByUnitID(uid));
|
||||
if (pItem == NULL)
|
||||
{
|
||||
vLog(LOG_DEBUG, "INFO: unknown link layer address(%i) -> ignore message\n", address);
|
||||
return 1;
|
||||
}
|
||||
UnitFeedDog(uid);
|
||||
}
|
||||
/* check checksum */
|
||||
BYTE checksum = 0;
|
||||
int i;
|
||||
for (i = csStart; i < csIndex; i++) checksum += msg [i];
|
||||
if (checksum != msg [csIndex])
|
||||
{
|
||||
vLog(LOG_DEBUG, "ERROR: checksum invalid!\n");
|
||||
llsu_setState(LL_STATE_ERROR);
|
||||
return 1;
|
||||
}
|
||||
/* parse C field bits */
|
||||
BOOLEAN prm = ((c & 0x40) == 0x40);
|
||||
if (prm == FALSE)
|
||||
{
|
||||
vLog(LOG_DEBUG, "ERROR: Received secondary message in unbalanced slave mode!\n");
|
||||
llsu_setState(LL_STATE_ERROR);
|
||||
return 1;
|
||||
}
|
||||
BOOLEAN fcb = ((c & 0x20) == 0x20);
|
||||
BOOLEAN fcv = ((c & 0x10) == 0x10);
|
||||
|
||||
LinkLayerSecondaryUnbalanced_ReceivedMessage(pItem, fc, isBroadcast, fcb, fcv, msg, userDataStart, userDataLength);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//不平衡方式从协议接收到主站报文
|
||||
void CIEC101SecondaryUnbalancedProcess::LinkLayerSecondaryUnbalanced_ReceivedMessage(CIEC101ProcessItem* pItem, BYTE fc, BOOLEAN isBroadcast, BOOLEAN fcb, BOOLEAN fcv, BYTE* msg, int userDataStart, int userDataLength)
|
||||
{
|
||||
pIEC101_LinkLayerSecondaryUnbalanced self = &(pItem->secondaryLinkUnbalanced);
|
||||
if (fcv)
|
||||
{
|
||||
if (checkFCB(self, fcb) == FALSE)
|
||||
{
|
||||
vLog(LOG_DEBUG, "SLL - FCB check failed\n");
|
||||
llsu_setState(LL_STATE_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
llsu_setState(LL_STATE_AVAILABLE);
|
||||
switch (fc)
|
||||
{
|
||||
case LL_FC_09_REQUEST_LINK_STATUS:
|
||||
//vLog(LOG_DEBUG, "SLL - REQUEST LINK STATUS\n");
|
||||
{
|
||||
BOOLEAN accessDemand = IsClass1DataAvailable(pItem);
|
||||
SendFixedFrame(LL_FC_11_STATUS_OF_LINK_OR_ACCESS_DEMAND, pItem->address, FALSE, FALSE, accessDemand, FALSE);
|
||||
}
|
||||
break;
|
||||
case LL_FC_00_RESET_REMOTE_LINK:
|
||||
//vLog(LOG_DEBUG, "SLL - RESET REMOTE LINK\n");
|
||||
{
|
||||
self->expectedFcb = TRUE;
|
||||
if (m_linkLayer.linkLayerParameters.useSingleCharACK)
|
||||
{
|
||||
SendSingleCharCharacter();
|
||||
}
|
||||
else
|
||||
{
|
||||
SendFixedFrame(LL_FC_00_ACK, pItem->address, FALSE, FALSE, FALSE, FALSE);
|
||||
}
|
||||
ResetCUReceived(pItem, FALSE);
|
||||
}
|
||||
break;
|
||||
case LL_FC_07_RESET_FCB:
|
||||
//vLog(LOG_DEBUG, "SLL - RESET FCB\n");
|
||||
{
|
||||
self->expectedFcb = TRUE;
|
||||
if (m_linkLayer.linkLayerParameters.useSingleCharACK)
|
||||
{
|
||||
SendSingleCharCharacter();
|
||||
}
|
||||
else
|
||||
{
|
||||
SendFixedFrame(LL_FC_00_ACK, pItem->address, FALSE, FALSE, FALSE, FALSE);
|
||||
}
|
||||
ResetCUReceived(pItem, TRUE);
|
||||
}
|
||||
break;
|
||||
case LL_FC_11_REQUEST_USER_DATA_CLASS_2:
|
||||
//vLog(LOG_DEBUG, "SLL - REQUEST USER DATA CLASS 2\n");
|
||||
{
|
||||
/* provide a buffer where the application layer can encode the user data */
|
||||
pIEC101_QueueElement element = GetClass2Data(pItem);
|
||||
BOOLEAN accessDemand = IsClass1DataAvailable(pItem);
|
||||
if (element)
|
||||
{
|
||||
SendVariableLengthFrame(LL_FC_08_RESP_USER_DATA, pItem->address, FALSE, FALSE, accessDemand, FALSE, element->buffer, element->size);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_linkLayer.linkLayerParameters.useSingleCharACK && !accessDemand)
|
||||
{
|
||||
SendSingleCharCharacter();
|
||||
}
|
||||
else
|
||||
{
|
||||
SendFixedFrame(LL_FC_09_RESP_NACK_NO_DATA, pItem->address, FALSE, FALSE, accessDemand, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LL_FC_10_REQUEST_USER_DATA_CLASS_1:
|
||||
//vLog(LOG_DEBUG, "SLL - REQUEST USER DATA CLASS 1\n");
|
||||
{
|
||||
/* provide a buffer where the application layer can encode the user data */
|
||||
pIEC101_QueueElement element = GetClass1Data(pItem);
|
||||
BOOLEAN accessDemand = IsClass1DataAvailable(pItem);
|
||||
if (element)
|
||||
{
|
||||
SendVariableLengthFrame(LL_FC_08_RESP_USER_DATA, pItem->address, FALSE, FALSE, accessDemand, FALSE, element->buffer, element->size);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_linkLayer.linkLayerParameters.useSingleCharACK && !accessDemand)
|
||||
{
|
||||
SendSingleCharCharacter();
|
||||
}
|
||||
else
|
||||
{
|
||||
SendFixedFrame(LL_FC_09_RESP_NACK_NO_DATA, pItem->address, FALSE, FALSE, accessDemand, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LL_FC_03_USER_DATA_CONFIRMED:
|
||||
//vLog(LOG_DEBUG, "SLL - USER DATA CONFIRMED\n");
|
||||
if (userDataLength > 0)
|
||||
{
|
||||
if (ApplicationLayer_ReceivedData(pItem, msg, isBroadcast, userDataStart, userDataLength))
|
||||
{
|
||||
BOOLEAN accessDemand = IsClass1DataAvailable(pItem);
|
||||
if (m_linkLayer.linkLayerParameters.useSingleCharACK && !accessDemand)
|
||||
{
|
||||
SendSingleCharCharacter();
|
||||
}
|
||||
else
|
||||
{
|
||||
SendFixedFrame(LL_FC_00_ACK, pItem->address, FALSE, FALSE, accessDemand, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LL_FC_04_USER_DATA_NO_REPLY:
|
||||
//vLog(LOG_DEBUG, "SLL - USER DATA NO REPLY\n");
|
||||
if (userDataLength > 0)
|
||||
{
|
||||
ApplicationLayer_ReceivedData(pItem, msg, isBroadcast, userDataStart, userDataLength);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//vLog(LOG_DEBUG, "SLL - UNEXPECTED LINK LAYER MESSAGE\n");
|
||||
SendFixedFrame(LL_FC_15_SERVICE_NOT_IMPLEMENTED, pItem->address, FALSE, FALSE, FALSE, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
#ifndef _ZJD_SUB_IEC101_UNBALANCED_PROCESS_H_
|
||||
#define _ZJD_SUB_IEC101_UNBALANCED_PROCESS_H_
|
||||
|
||||
#include "iec101.h"
|
||||
|
||||
class CIEC101SecondaryUnbalancedProcessItem : public CIEC101ProcessItem
|
||||
{
|
||||
public:
|
||||
CIEC101SecondaryUnbalancedProcessItem() {};
|
||||
virtual ~CIEC101SecondaryUnbalancedProcessItem() {};
|
||||
public:
|
||||
void Attach(int uid, int physicsAddress = 0, int commonAddress = 0, int originatorAddress = 0)
|
||||
{
|
||||
CIEC101ProcessItem::Attach(uid, physicsAddress, commonAddress, m_originatorAddress);
|
||||
primaryLinkBalanced.otherStationAddress = physicsAddress;
|
||||
common_address = commonAddress;
|
||||
applicationlParameters.originatorAddress = originatorAddress;
|
||||
}
|
||||
void setAppLayerDataCount(int yx = 0, int yc = 0, int ym = 0)
|
||||
{
|
||||
total_yx = yx;
|
||||
total_yc = yc;
|
||||
total_ym = ym;
|
||||
yx_pos = 0;
|
||||
yc_pos = 0;
|
||||
ym_pos = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class CIEC101SecondaryUnbalancedProcess : public CIEC101SecondaryProcess
|
||||
{
|
||||
private:
|
||||
enumIEC101_LinkLayerState m_state;
|
||||
QWORD m_lastReceivedMsg;
|
||||
int m_idleTimeout; /* connection timeout in ms */
|
||||
public:
|
||||
CIEC101SecondaryUnbalancedProcess()
|
||||
{
|
||||
m_linkLayer.mode = llSecUnbalanced;
|
||||
m_state = LL_STATE_IDLE;
|
||||
}
|
||||
virtual ~CIEC101SecondaryUnbalancedProcess() {};
|
||||
BOOLEAN OnPreCreate(int id);
|
||||
BOOLEAN Run(void);
|
||||
BOOLEAN OnTimer(void);
|
||||
|
||||
CIEC101ProcessItem *CreateItem(int ord)
|
||||
{
|
||||
return dynamic_cast<CIEC101ProcessItem *>(new CIEC101SecondaryUnbalancedProcessItem);
|
||||
}
|
||||
|
||||
void Slave_setLinkLayerAddressOtherStation(CIEC101ProcessItem* pItem, int address)
|
||||
{
|
||||
pItem->address = address;
|
||||
}
|
||||
|
||||
int OnPackageReceived(BYTE* pBuf, int count, int ord = -1);
|
||||
private:
|
||||
void llsu_setState(enumIEC101_LinkLayerState newState)
|
||||
{
|
||||
if (m_state != newState)
|
||||
{
|
||||
m_state = newState;
|
||||
}
|
||||
}
|
||||
BOOLEAN checkFCB(pIEC101_LinkLayerSecondaryUnbalanced self, BOOLEAN fcb)
|
||||
{
|
||||
if (fcb != self->expectedFcb) return FALSE;
|
||||
self->expectedFcb = !(self->expectedFcb);
|
||||
return TRUE;
|
||||
}
|
||||
void ResetCUReceived(CIEC101ProcessItem* pItem, bool onlyFCB)
|
||||
{
|
||||
if (onlyFCB)
|
||||
{
|
||||
//vLog(LOG_DEBUG, "CS101 slave: Reset FCB received\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//vLog(LOG_DEBUG, "Received reset CU\n");
|
||||
pItem->userDataClass1Queue.flush();
|
||||
pItem->userDataClass2Queue.flush();
|
||||
}
|
||||
}
|
||||
void LinkLayerSecondaryUnbalanced_ReceivedMessage(CIEC101ProcessItem* self, BYTE fc, BOOLEAN isBroadcast, BOOLEAN fcb, BOOLEAN fcv, BYTE* msg, int userDataStart, int userDataLength);
|
||||
};
|
||||
|
||||
#endif // _ZJD_SUB_IEC101_UNBALANCED_PROCESS_H_
|
File diff suppressed because it is too large
Load Diff
@ -1,92 +0,0 @@
|
||||
#ifndef _ZJD_SUB_MODBUS_RTU_TCP_PROCESS_H_
|
||||
#define _ZJD_SUB_MODBUS_RTU_TCP_PROCESS_H_
|
||||
|
||||
#include "netproc.h"
|
||||
#include "modbus_def.h"
|
||||
#include <vector>
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct
|
||||
{
|
||||
struNetWorkOption net;
|
||||
BYTE defaultYCType;
|
||||
} struSubModbusTCPOption;
|
||||
#pragma pack()
|
||||
|
||||
typedef std::vector<int> vecInt;
|
||||
|
||||
class CSubModbusTcpProcessItem : public CNetProcessItem
|
||||
{
|
||||
public:
|
||||
BYTE ied_addr;
|
||||
WORD m_nNum;
|
||||
|
||||
short m_CoilRegCount;
|
||||
short m_DiscreteRegCount;
|
||||
short m_HoldingRegCount;
|
||||
short m_InputregCount;
|
||||
|
||||
BYTE *m_pCoilRegTable;
|
||||
BYTE *m_pDiscreteRegTable;
|
||||
WORD *m_pHoldingRegTable;
|
||||
WORD *m_pInputRegTable;
|
||||
|
||||
public:
|
||||
CSubModbusTcpProcessItem();
|
||||
virtual ~CSubModbusTcpProcessItem();
|
||||
|
||||
void Attach(int uid, int sock, DWORD peer_addr, WORD peer_port);
|
||||
void Release(void);
|
||||
|
||||
};
|
||||
|
||||
class CSubModbusTcpProcess : public CNetProcess
|
||||
{
|
||||
public:
|
||||
CSubModbusTcpProcess();
|
||||
virtual ~CSubModbusTcpProcess();
|
||||
|
||||
CNetProcessItem *CreateItem(int ord);
|
||||
void DestroyItem(int ord, BOOLEAN bDeleted = FALSE);
|
||||
|
||||
virtual BOOLEAN OnPreCreate(int id);
|
||||
virtual BOOLEAN Run(void);
|
||||
virtual BOOLEAN OnTimer(void);
|
||||
private:
|
||||
struSubModbusTCPOption m_option;
|
||||
BYTE m_YC_Type;
|
||||
enum
|
||||
{
|
||||
M_ME_NA,
|
||||
M_ME_NC
|
||||
};
|
||||
|
||||
vecInt m_CoilRegTable;
|
||||
vecInt m_DiscreteTable;
|
||||
vecInt m_HoldingRegTable;
|
||||
vecInt m_InputRegTable;
|
||||
|
||||
private:
|
||||
int OnPackageReceived(BYTE* pBuf, int count, int ord /* = -1 */);
|
||||
BOOLEAN OnReceiveData(CSubModbusTcpProcessItem *pItem, BYTE* pData, int count, int uid);
|
||||
|
||||
eMBErrorCode eMBTCPSend(BYTE ucSlaveAddress, const BYTE *pucFrame, WORD usLength);
|
||||
|
||||
eMBException prveMBError2Exception(eMBErrorCode eErrorCode);
|
||||
eMBException eMBFuncReadInputRegister(CSubModbusTcpProcessItem *pItem, BYTE* pucFrame, WORD* usLen);
|
||||
eMBException eMBFuncReadHoldingRegister(CSubModbusTcpProcessItem *pItem, BYTE* pucFrame, WORD* usLen);
|
||||
eMBException eMBFuncWriteHoldingRegister(CSubModbusTcpProcessItem *pItem, BYTE* pucFrame, WORD* usLen);
|
||||
eMBException eMBFuncWriteMultipleHoldingRegister(CSubModbusTcpProcessItem *pItem, BYTE* pucFrame, WORD* usLen);
|
||||
eMBException eMBFuncReadCoils(CSubModbusTcpProcessItem *pItem, BYTE* pucFrame, WORD* usLen);
|
||||
eMBException eMBFuncWriteCoil(CSubModbusTcpProcessItem *pItem, BYTE* pucFrame, WORD* usLen);
|
||||
eMBException eMBFuncWriteMultipleCoils(CSubModbusTcpProcessItem *pItem, BYTE* pucFrame, WORD* usLen);
|
||||
eMBException eMBFuncReadDiscreteInputs(CSubModbusTcpProcessItem *pItem, BYTE* pucFrame, WORD* usLen);
|
||||
|
||||
|
||||
eMBErrorCode eMBRegInputCB(CSubModbusTcpProcessItem *pItem, BYTE* pucRegBuffer, WORD usAddress, WORD usNRegs);
|
||||
eMBErrorCode eMBRegHoldingCB(CSubModbusTcpProcessItem *pItem, BYTE* pucRegBuffer, WORD usAddress, WORD usNRegs, eMBRegisterMode eMode);
|
||||
eMBErrorCode eMBRegCoilsCB(CSubModbusTcpProcessItem *pItem, BYTE* pucRegBuffer, WORD usAddress, WORD usNCoils, eMBRegisterMode eMode);
|
||||
eMBErrorCode eMBRegDiscreteCB(CSubModbusTcpProcessItem *pItem, BYTE* pucRegBuffer, WORD usAddress, WORD usNDiscrete);
|
||||
};
|
||||
|
||||
#endif //_ZJD_SUB_MODBUS_RTU_TCP_PROCESS_H_
|
Loading…
Reference in New Issue
Block a user