2024-07-08 10:27:17 +08:00
# include "sub_gdw104.h"
# include <fstream>
//国网DLT634.5104-2009实施细则(试行)
static const BYTE GDW_M_FT_NA_1 = 0x2A ; //故障事件
static const BYTE GDW_M_KY_NA_1 = 0x6C ; //108 ECC公钥传输报文
static const BYTE GDW_C_SE_ND_1 = 0x88 ; //多点设定 归一化
static const BYTE GDW_C_SR_NA_1 = 0xC8 ; //切换定值区
static const BYTE GDW_C_RR_NA_1 = 0xC9 ; //读取定值区
static const BYTE GDW_C_RS_NA_1 = 0xCA ; //读取定值
static const BYTE GDW_C_WS_NA_1 = 0xCB ; //设定定值
static const BYTE GDW_M_IT_NB_1 = 0xCE ; //累计量,短浮点数
static const BYTE GDW_M_IT_TC_1 = 0xCF ; //带CP56Time2a时标的累计量, 短浮点数
static const BYTE GDW_M_EM_NA_1 = 0xCE ; //电量当前值
static const BYTE GDW_M_FM_NA_1 = 0xCF ; //电量冻结值
static const BYTE GDW_F_FR_NA_1 = 0xD2 ; //文件传输
static const BYTE GDW_F_SR_NA_1 = 0xD3 ; //软件升级
static const BYTE FILE_TRS_TYPE = 0x02 ;
static const BYTE ReadFileDirAct = 0x01 ;
static const BYTE ReadFileDirCon = 0x02 ;
static const BYTE ReadFileSelAct = 0x03 ;
static const BYTE ReadFileSelCon = 0x04 ;
static const BYTE ReadFileDataAct = 0x05 ;
static const BYTE ReadFileDataCon = 0x06 ;
static const BYTE WriteFileSelAct = 0x07 ;
static const BYTE WriteFileSelCon = 0x08 ;
static const BYTE WriteFileDataAct = 0x09 ;
static const BYTE WriteFileDataCon = 0x0A ;
# define FILE_SOE_PATH_NAME "%s / soe.msg"
# define FILE_CO_PATH_NAME "%s / co.msg"
# define FILE_EXV_PATH_NAME "%s / exv%04d%02d%02d.msg"
# define FILE_FIXPT_PATH_NAME "%s / fixpt%04d%02d%02d.msg"
# define FILE_FRZ_PATH_NAME "%s / frz%04d%02d%02d.msg"
# define FILE_FLOWREV_PATH_NAME "%s / flowrev.msg"
# define FILE_ULOG_PATH_NAME "%s / ulog.msg"
static const value_string yk_type [ ] =
{
{ YKT_NULL , " 空闲 " } ,
{ YKT_SELREQ , " 选择 " } ,
{ YKT_SELRET , " 选择确认 " } ,
{ YKT_ABRREQ , " 撤销 " } ,
{ YKT_EXEREQ , " 执行 " } ,
{ YKT_EXERET , " 执行确认 " }
} ;
static void * main_file_process ( void * param )
{
CGDW104FileProcess * proc = ( CGDW104FileProcess * ) param ;
DWORD old_ticks = 0 ;
while ( TRUE )
{
if ( old_ticks ! = system32 . ticks )
{
old_ticks = system32 . ticks ;
proc - > OnTimer ( ) ;
}
usleep ( 5000 ) ;
}
pthread_exit ( 0 ) ;
return ( ( void * ) 0 ) ;
}
BOOLEAN CGDW104FileProcess : : SaveMapToFile ( void )
{
std : : ofstream file ( " gdw104mapext.dmp " ) ;
if ( file . is_open ( ) )
{
std : : map < int , STRUCT_YCEXTREMUM > : : iterator it ;
file < < system32 . timers < < std : : endl ;
for ( it = mapYcExetremumRecordDatas . begin ( ) ; it ! = mapYcExetremumRecordDatas . end ( ) ; it + + )
{
file < < it - > first < < " " \
< < it - > second . datetime < < " " \
< < it - > second . fMaxVal < < " " \
< < it - > second . fMinVal < < " " \
< < it - > second . fCoef < < " " \
< < it - > second . fBase < < " " \
< < it - > second . iMaxVal < < " " \
< < it - > second . iMinVal < < " " \
< < it - > second . MaxTime < < " " \
< < it - > second . MinTime < < " " \
< < it - > second . iCurVal < < std : : endl ;
}
file . close ( ) ;
return TRUE ;
}
return FALSE ;
}
BOOLEAN CGDW104FileProcess : : LoadMapFromFile ( int size )
{
std : : ifstream file ( " gdw104mapext.dmp " ) ;
if ( file . is_open ( ) )
{
int count = 0 ;
std : : string line ;
int key ;
STRUCT_YCEXTREMUM value ;
mapYcExetremumRecordDatas . clear ( ) ;
while ( std : : getline ( file , line ) )
{
std : : stringstream stream ( line ) ;
if ( count = = 0 )
{
LONG dt ;
stream > > dt ;
m_last_day = Time_ttounionCP56Time ( ( time_t ) dt ) . dayofmonth ;
if ( m_last_day < = 0 )
{
file . close ( ) ;
return FALSE ;
}
}
else
{
stream > > key > > value . datetime > > value . fMaxVal > > value . fMinVal > > value . fCoef > > value . fBase > > value . iMaxVal > > value . iMinVal > > value . MaxTime > > value . MinTime > > value . iCurVal ;
if ( mapYcExetremumRecordDatas . find ( key ) = = mapYcExetremumRecordDatas . end ( ) )
{
mapYcExetremumRecordDatas . insert ( std : : map < int , STRUCT_YCEXTREMUM > : : value_type ( key , value ) ) ;
}
}
count + + ;
}
file . close ( ) ;
if ( size ! = ( count - 1 ) )
{
vLog ( LOG_ERROR , " yccount is: %d, and count is: %d \n " , size , count ) ;
unlink ( " gdw104mapext.dmp " ) ;
return FALSE ;
}
return TRUE ;
}
return FALSE ;
}
BYTE CGDW104FileProcess : : GetCheckSum8 ( BYTE * pData , int count )
{
int i ;
BYTE result = 0 ;
BYTE * pBuf = pData ;
for ( i = 0 ; i < count ; i + + )
{
result + = * pBuf ;
pBuf + + ;
}
return result ;
}
void CGDW104FileProcess : : delete_files_in_dir ( const char * folder_path )
{
DIR * dir ;
struct dirent * entry ;
char file_path [ 256 ] ;
// 打开目录
dir = opendir ( folder_path ) ;
if ( dir = = NULL )
{
vLog ( LOG_ERROR , " 无法打开目录:%s " , folder_path ) ;
return ;
}
// 遍历目录
while ( ( entry = readdir ( dir ) ) ! = NULL )
{
// 忽略当前目录和上级目录
if ( strcmp ( entry - > d_name , " . " ) = = 0 | | strcmp ( entry - > d_name , " .. " ) = = 0 )
{
continue ;
}
// 构建文件路径
snprintf ( file_path , sizeof ( file_path ) , " %s/%s " , folder_path , entry - > d_name ) ;
// 检查文件类型
struct stat statbuf ;
if ( lstat ( file_path , & statbuf ) = = - 1 )
{
vLog ( LOG_ERROR , " 获取文件<%s>状态失败(%d,%s) \n " , file_path , errno , strerror ( errno ) ) ;
return ;
}
// 如果是文件则删除
if ( S_ISREG ( statbuf . st_mode ) )
{
if ( unlink ( file_path ) ! = 0 )
{
vLog ( LOG_ERROR , " 删除文件<%s>失败(%d,%s) " , file_path , errno , strerror ( errno ) ) ;
return ;
}
}
// 如果是文件夹则递归删除
else if ( S_ISDIR ( statbuf . st_mode ) )
{
delete_files_in_dir ( file_path ) ;
}
}
// 关闭目录
closedir ( dir ) ;
}
BOOLEAN CGDW104FileProcess : : OnCreate ( int uid , const void * pUnit , const void * param )
{
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
if ( pUnit = = NULL | | param = = NULL ) return FALSE ;
mapYcExetremumRecordDatas . clear ( ) ;
m_uid = uid ;
struGDW104Option m_nOption = * ( struGDW104Option * ) param ;
struUnit unit = * ( struUnit * ) pUnit ;
m_pUnitYM = NULL ;
if ( unit . ymcount )
{
m_total_ym = unit . ymcount ;
m_pUnitYM = new struUnitYM [ unit . ymcount ] ;
if ( m_pUnitYM )
{
memcpy ( m_pUnitYM , unit . yms , sizeof ( struUnitYM ) * unit . ymcount ) ;
}
}
m_information_address_length = m_nOption . iec104 . info_addr_size ;
m_yx_information_address_start = m_nOption . iec104 . yx_start_address ;
m_yc_information_address_start = m_nOption . iec104 . yc_start_address ;
m_ym_information_address_start = m_nOption . iec104 . ym_start_address ;
if ( m_nOption . soeDir [ 0 ] = = ' \0 ' ) str_SOERecordDir = " soe " ;
else str_SOERecordDir = m_nOption . soeDir ;
if ( m_nOption . coDir [ 0 ] = = ' \0 ' ) str_coRecordDir = " co " ;
else str_coRecordDir = m_nOption . coDir ;
if ( m_nOption . fixptDir [ 0 ] = = ' \0 ' ) str_fixptRecordDir = " fixpt " ;
else str_fixptRecordDir = m_nOption . fixptDir ;
if ( m_nOption . exvDir [ 0 ] = = ' \0 ' ) str_exvRecordDir = " exv " ;
else str_exvRecordDir = m_nOption . exvDir ;
if ( m_nOption . frzDir [ 0 ] = = ' \0 ' ) str_frzRecordDir = " frz " ;
else str_frzRecordDir = m_nOption . frzDir ;
if ( m_nOption . flowrevDir [ 0 ] = = ' \0 ' ) str_flowrevRecordDir = " flowrev " ;
else str_flowrevRecordDir = m_nOption . flowrevDir ;
if ( m_nOption . ulogDir [ 0 ] = = ' \0 ' ) str_ulogRecordDir = " ulog " ;
else str_ulogRecordDir = m_nOption . ulogDir ;
//根据配置来创建文件夹
mkLogDir ( str_SOERecordDir . c_str ( ) ) ;
mkLogDir ( str_coRecordDir . c_str ( ) ) ;
mkLogDir ( str_fixptRecordDir . c_str ( ) ) ;
mkLogDir ( str_exvRecordDir . c_str ( ) ) ;
mkLogDir ( str_frzRecordDir . c_str ( ) ) ;
mkLogDir ( str_flowrevRecordDir . c_str ( ) ) ;
mkLogDir ( str_ulogRecordDir . c_str ( ) ) ;
char pathName [ 512 ] ;
FILE * pf ;
snprintf ( pathName , sizeof ( pathName ) , " %s/%s " , configpath , FILE_UNIT_STATIC ) ;
pf = fopen ( pathName , " rb " ) ;
if ( pf )
{
memset ( & m_unit , ' \0 ' , sizeof ( m_unit ) ) ;
if ( fseek ( pf , sizeof ( struUnitStatic ) * uid , SEEK_SET ) = = 0 )
{
fread ( & m_unit , sizeof ( struUnitStatic ) , 1 , pf ) ;
}
fclose ( pf ) ;
}
//创建极值列表
if ( ! LoadMapFromFile ( unit . yccount ) )
{
for ( int i = 0 ; i < unit . yccount ; i + + )
{
STRUCT_YCEXTREMUM data ;
data . datetime = system32 . timers ;
data . iMaxVal = 0x80000000 ;
data . iMinVal = 0x7FFFFFFF ;
data . MaxTime = system32 . timers ;
data . MinTime = system32 . timers ;
data . fCoef = unit . ycs [ i ] . coef ;
data . fBase = unit . ycs [ i ] . base ;
if ( mapYcExetremumRecordDatas . find ( i ) = = mapYcExetremumRecordDatas . end ( ) )
{
mapYcExetremumRecordDatas . insert ( std : : map < int , STRUCT_YCEXTREMUM > : : value_type ( i , data ) ) ;
}
}
}
m_database . Open ( " ./gdw104.db " , SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE , 0 ) ;
m_database . MoveDatabaseToMemory ( ) ;
//创建数据库表
try
{
SQLiteStatement * pStmt = new SQLiteStatement ( & m_database ) ;
pStmt - > SqlStatement ( " CREATE TABLE IF NOT EXISTS SOE_RECORD_TABLE ( "
" Yxpoint INTEGER NOT NULL, "
" Yxvalue INTEGER NOT NULL, "
" Yxdatetime INTEGER NOT NULL, "
" Yxmillisecond INTEGER NOT NULL, "
" CONSTRAINT SOE_RECORD_TABLE_PK PRIMARY KEY (Yxpoint, Yxvalue, Yxdatetime, Yxmillisecond)); " ) ;
pStmt - > SqlStatement ( " CREATE TABLE IF NOT EXISTS YKLOG_RECORD_TABLE ( "
" Ykpoint INTEGER NOT NULL, "
" Yktype INTEGER NOT NULL, "
" Ykvalue INTEGER NOT NULL, "
" Ykdatetime INTEGER NOT NULL, "
" Ykmillisecond INTEGER NOT NULL, "
" CONSTRAINT YKLOG_RECORD_TABLE_PK PRIMARY KEY (Ykpoint, Yktype, Ykvalue, Ykdatetime, Ykmillisecond)); " ) ;
//创建极值库
pStmt - > SqlStatement ( " CREATE TABLE IF NOT EXISTS YCEXV_RECORD_TABLE ( "
" Ycpoint INTEGER NOT NULL, "
" Ycdatetime INTEGER NOT NULL, "
" YciMaxval INTEGER NOT NULL, "
" YciMinval INTEGER NOT NULL, "
" YcfMaxval REAL NOT NULL, "
" YcfMinval REAL NOT NULL, "
" YcMaxdatetime INTEGER NOT NULL, "
" YcMindatetime INTEGER NOT NULL, "
" CONSTRAINT YCEXV_RECORD_TABLE_PK PRIMARY KEY (Ycpoint, Ycdatetime)); " ) ;
//创建遥测历史数据表YcHisRecordTable
pStmt - > SqlStatement ( " CREATE TABLE IF NOT EXISTS YCHIS_RECORD_TABLE ( "
" Ycpoint INTEGER NOT NULL, "
" Ycdatetime INTEGER NOT NULL, "
" YciVal INTEGER NOT NULL, "
" Ycfval REAL NOT NULL, "
" CONSTRAINT YCHIS_RECORD_TABLE PRIMARY KEY (Ycpoint, Ycdatetime)); " ) ;
//创建冻结电度量表
pStmt - > SqlStatement ( " CREATE TABLE IF NOT EXISTS FMHIS_RECORD_TABLE ( "
" Ympoint INTEGER NOT NULL, "
" Ymdatetime INTEGER NOT NULL, "
" YmiVal INTEGER NOT NULL, "
" Ymfval REAL NOT NULL, "
" CONSTRAINT FMHIS_RECORD_TABLE PRIMARY KEY (Ympoint, Ymdatetime)); " ) ;
//比较表空间
delete pStmt ;
}
catch ( SQLiteException & exception )
{
vLog ( LOG_ERROR , " \n Exception Occured " ) ;
exception . Show ( ) ;
vLog ( LOG_ERROR , " SQLite result code: %d,%s \n " , exception . GetSqliteResultCode ( ) , exception . GetErrorDescription ( ) . c_str ( ) ) ;
return FALSE ;
}
return TRUE ;
}
BOOLEAN CGDW104FileProcess : : OnTimer ( void )
{
BOOLEAN sec_changed = FALSE ;
if ( last_sec ! = system32 . timers )
{
last_sec = system32 . timers ;
sec_changed = TRUE ;
}
do
{
if ( m_nCmdID = = FIOCMD_OPEN_FILE )
{
m_nCmdID = 0 ;
if ( m_pFileHandle )
{
fclose ( m_pFileHandle ) ;
m_pFileHandle = NULL ;
}
m_pFileHandle = fopen ( m_pathName . c_str ( ) , m_bWr ? " wb+ " : " rb " ) ;
if ( m_pFileHandle = = NULL ) m_nCmdIDConfirm | = CMD_EXEC_ERR ;
//获取文件长度
m_nFileLength = FileLength ( m_pathName ) ;
m_nCmdIDConfirm = FIOCMD_OPEN_FILE ;
}
else if ( m_nCmdID = = FIOCMD_CLOSE_FILE )
{
m_nCmdID = 0 ;
if ( m_pFileHandle )
{
fclose ( m_pFileHandle ) ;
m_pFileHandle = NULL ;
}
m_nFileLength = 0 ;
m_nFilePos = 0 ;
m_nReadLen = 0 ;
}
else if ( m_nCmdID = = FIOCMD_READ_FILE )
{
m_nCmdID = 0 ;
if ( fseek ( m_pFileHandle , m_nFilePos , SEEK_SET ) ! = 0 )
{
m_nCmdIDConfirm | = CMD_EXEC_ERR ;
}
else
{
int count = ( FileLeftLength ( ) > MAX_FILEDATA_LEN ) ? MAX_FILEDATA_LEN : FileLeftLength ( ) ;
fread ( ( char * ) m_fileBuffer , count , 1 , m_pFileHandle ) ;
m_nReadLen = count ;
}
m_nCmdIDConfirm = FIOCMD_READ_FILE ;
}
else if ( m_nCmdID = = FIOCMD_READ_DIR )
{
//删除目录下所有文件
delete_files_in_dir ( str_SOERecordDir . c_str ( ) ) ;
delete_files_in_dir ( str_coRecordDir . c_str ( ) ) ;
delete_files_in_dir ( str_exvRecordDir . c_str ( ) ) ;
delete_files_in_dir ( str_fixptRecordDir . c_str ( ) ) ;
delete_files_in_dir ( str_frzRecordDir . c_str ( ) ) ;
delete_files_in_dir ( str_flowrevRecordDir . c_str ( ) ) ;
delete_files_in_dir ( str_ulogRecordDir . c_str ( ) ) ;
m_nCmdID = 0 ;
//生成事件记录文件
createSOEFile ( ) ;
//生成遥控记录文件
createYKLogFile ( ) ;
//生成极值文件
createExtremumRecordFile ( ) ;
//生成遥测定点记录数据文件
createYCHisRecordFile ( ) ;
//生成冻结数据文件
createFmHisRecordFile ( ) ;
//将数据保存到本地数据库
m_database . SaveDatabaseFromMemoryToFile ( " ./gdw104.db " ) ;
if ( ReadDir ( m_pathName . c_str ( ) ) < = 0 )
{
vLog ( LOG_ERROR , " Read %s dir error. \n " , m_pathName . c_str ( ) ) ;
m_nCmdIDConfirm | = CMD_EXEC_ERR ;
}
m_nCmdIDConfirm = FIOCMD_READ_DIR ;
}
} while ( 0 ) ;
if ( sec_changed )
{
DumpSOE ( ) ;
DumpYKLog ( ) ;
if ( m_last_day ! = system32 . now . dayofmonth )
{
UpdateExtremumRecord ( TRUE ) ;
m_last_day = system32 . now . dayofmonth ;
}
else
{
UpdateExtremumRecord ( FALSE ) ;
}
if ( ( system32 . timers % 300 ) = = 0 ) //此处最好根据配置来设置定点数据频率
{ //5分钟保存一次
//保存一次遥测历史
DumpYCHisRecord ( system32 . timers ) ;
//保存一次冻结数据
DumpFmHisRecord ( system32 . timers ) ;
// save the memory database to a file
m_database . SaveDatabaseFromMemoryToFile ( " ./gdw104.db " ) ;
}
}
return TRUE ;
}
void CGDW104FileProcess : : createSOEFile ( void )
{
int count = 0 ;
char sql [ 512 ] ;
char query [ 512 ] ;
SQLiteStatement * pStmt = new SQLiteStatement ( & m_database ) ;
try
{
//生成soe文件
if ( m_bCallAllFile )
{
snprintf ( query , sizeof ( query ) , " SELECT * FROM SOE_RECORD_TABLE; " ) ;
count = ( int ) pStmt - > SqlAggregateFuncResult ( " SELECT COUNT(*) FROM SOE_RECORD_TABLE; " ) ;
}
else
{
snprintf ( sql , sizeof ( sql ) , " SELECT COUNT(*) FROM SOE_RECORD_TABLE WHERE Yxdatetime >= %d AND Yxdatetime <= %d; " , ( DWORD ) m_start_time , ( DWORD ) m_end_time ) ;
snprintf ( query , sizeof ( query ) , " SELECT * FROM SOE_RECORD_TABLE WHERE Yxdatetime >= %d AND Yxdatetime <= %d; " , ( DWORD ) m_start_time , ( DWORD ) m_end_time ) ;
count = ( int ) pStmt - > SqlAggregateFuncResult ( sql ) ;
}
char text [ 64 ] ;
snprintf ( text , sizeof ( text ) , FILE_SOE_PATH_NAME , str_SOERecordDir . c_str ( ) ) ;
FILE * pf = fopen ( text , " wb+ " ) ;
if ( pf ! = NULL )
{
fprintf ( pf , " soe.msg, v1.0 \r \n %s,%02d,%02d \r \n " , m_unit . name , count , m_information_address_length ) ;
pStmt - > BeginTransaction ( ) ;
pStmt - > Sql ( query ) ;
while ( pStmt - > FetchRow ( ) )
{
char buffer [ 32 ] ;
struct tm info ;
time_t t = ( time_t ) pStmt - > GetColumnInt ( 2 ) ;
localtime_r ( & t , & info ) ;
strftime ( buffer , sizeof ( buffer ) , " %Y-%m-%d %H:%M:%S " , & info ) ;
fprintf ( pf , " %04x,%d,%s.%3d \r \n " ,
pStmt - > GetColumnInt ( 0 ) + m_yx_information_address_start ,
pStmt - > GetColumnInt ( 1 ) ,
buffer ,
pStmt - > GetColumnInt ( 3 ) ) ;
}
pStmt - > FreeQuery ( ) ;
pStmt - > CommitTransaction ( ) ;
fclose ( pf ) ;
}
}
catch ( SQLiteException & exception )
{
vLog ( LOG_ERROR , " \n Exception Occured " ) ;
exception . Show ( ) ;
vLog ( LOG_ERROR , " SQLite result code: %d,%s \n " , exception . GetSqliteResultCode ( ) , exception . GetErrorDescription ( ) . c_str ( ) ) ;
}
delete pStmt ;
}
void CGDW104FileProcess : : createYKLogFile ( void )
{
int count = 0 ;
char sql [ 512 ] ;
char query [ 512 ] ;
SQLiteStatement * pStmt = new SQLiteStatement ( & m_database ) ;
try
{
if ( m_bCallAllFile )
{
snprintf ( query , sizeof ( query ) , " SELECT * FROM YKLOG_RECORD_TABLE; " ) ;
count = ( int ) pStmt - > SqlAggregateFuncResult ( " SELECT COUNT(*) FROM YKLOG_RECORD_TABLE; " ) ;
}
else
{
snprintf ( sql , sizeof ( sql ) , " SELECT COUNT(*) FROM YKLOG_RECORD_TABLE WHERE Yxdatetime >= %d AND Yxdatetime <= %d; " , ( DWORD ) m_start_time , ( DWORD ) m_end_time ) ;
snprintf ( query , sizeof ( query ) , " SELECT * FROM YKLOG_RECORD_TABLE WHERE Yxdatetime >= %d AND Yxdatetime <= %d; " , ( DWORD ) m_start_time , ( DWORD ) m_end_time ) ;
count = ( int ) pStmt - > SqlAggregateFuncResult ( sql ) ;
}
char text [ 64 ] ;
snprintf ( text , sizeof ( text ) , FILE_CO_PATH_NAME , str_coRecordDir . c_str ( ) ) ;
FILE * pf = fopen ( text , " wb+ " ) ;
if ( pf ! = NULL )
{
fprintf ( pf , " co.msg, v1.0 \r \n %s,%02d,%02d \r \n " , m_unit . name , count , m_information_address_length ) ;
pStmt - > BeginTransaction ( ) ;
pStmt - > Sql ( query ) ;
while ( pStmt - > FetchRow ( ) )
{
char buffer [ 32 ] ;
struct tm info ;
time_t t = ( time_t ) pStmt - > GetColumnInt ( 3 ) ;
localtime_r ( & t , & info ) ;
strftime ( buffer , sizeof ( buffer ) , " %Y-%m-%d %H:%M:%S " , & info ) ;
fprintf ( pf , " %04x,%s,%s,%s.%03d \r \n " ,
pStmt - > GetColumnInt ( 0 ) ,
val_to_str ( pStmt - > GetColumnInt ( 1 ) , yk_type , " STATE=%d " ) ,
pStmt - > GetColumnInt ( 2 ) ? " 合 " : " 分 " ,
buffer ,
pStmt - > GetColumnInt ( 4 ) ) ;
}
pStmt - > FreeQuery ( ) ;
pStmt - > CommitTransaction ( ) ;
fclose ( pf ) ;
}
}
catch ( SQLiteException & exception )
{
vLog ( LOG_ERROR , " \n Exception Occured " ) ;
exception . Show ( ) ;
vLog ( LOG_ERROR , " SQLite result code: %d,%s \n " , exception . GetSqliteResultCode ( ) , exception . GetErrorDescription ( ) . c_str ( ) ) ;
}
delete pStmt ;
}
void CGDW104FileProcess : : createExtremumRecordFile ( void )
{
char query [ 512 ] ;
SQLiteStatement * pStmt = new SQLiteStatement ( & m_database ) ;
try
{
if ( m_bCallAllFile )
{
snprintf ( query , sizeof ( query ) , " SELECT * FROM YCEXV_RECORD_TABLE; " ) ;
}
else
{
snprintf ( query , sizeof ( query ) , " SELECT * FROM YCEXV_RECORD_TABLE WHERE Ycdatetime >= %d AND Ycdatetime <= %d; " , ( DWORD ) m_start_time , ( DWORD ) m_end_time ) ;
}
std : : map < std : : string , STRUCT_FILEBUFFER > mapExvFileBuffers ;
mapExvFileBuffers . clear ( ) ;
pStmt - > BeginTransaction ( ) ;
pStmt - > Sql ( query ) ;
while ( pStmt - > FetchRow ( ) )
{
char buffer [ 256 ] ;
unionCP56Time ut = Time_ttounionCP56Time ( ( time_t ) pStmt - > GetColumnInt ( 1 ) ) ;
snprintf ( buffer , sizeof ( buffer ) , FILE_EXV_PATH_NAME , str_exvRecordDir . c_str ( ) , ut . year + 2000 , ut . month , ut . dayofmonth ) ;
std : : string filename = buffer ;
std : : string maxbuffer ;
std : : string minbuffer ;
int point = pStmt - > GetColumnInt ( 0 ) ;
float maxVal = pStmt - > GetColumnDouble ( 4 ) ;
float minVal = pStmt - > GetColumnDouble ( 5 ) ;
unionCP56Time maxTime = Time_ttounionCP56Time ( ( time_t ) pStmt - > GetColumnInt ( 6 ) ) ;
unionCP56Time minTime = Time_ttounionCP56Time ( ( time_t ) pStmt - > GetColumnInt ( 7 ) ) ;
snprintf ( buffer , sizeof ( buffer ) , " %4x,%4.3f,%04d-%02d-%02d %02d:%02d:%02d.%03d " , point + m_yc_information_address_start , maxVal ,
maxTime . year + 2000 , maxTime . month , maxTime . dayofmonth , maxTime . hour , maxTime . minute , maxTime . millisecond / 1000 , maxTime . millisecond % 1000 ) ;
maxbuffer = buffer ;
snprintf ( buffer , sizeof ( buffer ) , " %4x,%4.3f,%04d-%02d-%02d %02d:%02d:%02d.%03d " , point + m_yc_information_address_start , minVal ,
minTime . year + 2000 , minTime . month , minTime . dayofmonth , minTime . hour , minTime . minute , minTime . millisecond / 1000 , minTime . millisecond % 1000 ) ;
minbuffer = buffer ;
if ( mapExvFileBuffers . find ( filename ) = = mapExvFileBuffers . end ( ) )
{
STRUCT_FILEBUFFER fb ;
fb . count = 1 ;
fb . ss_outmax = maxbuffer ;
fb . ss_outmin = minbuffer ;
mapExvFileBuffers . insert ( std : : map < std : : string , STRUCT_FILEBUFFER > : : value_type ( filename , fb ) ) ;
}
else
{
mapExvFileBuffers [ filename ] . count + + ;
mapExvFileBuffers [ filename ] . ss_outmax + = " , " + maxbuffer ;
mapExvFileBuffers [ filename ] . ss_outmin + = " , " + minbuffer ;
}
}
pStmt - > FreeQuery ( ) ;
pStmt - > CommitTransaction ( ) ;
std : : map < std : : string , STRUCT_FILEBUFFER > : : iterator it ;
for ( it = mapExvFileBuffers . begin ( ) ; it ! = mapExvFileBuffers . end ( ) ; it + + )
{
FILE * pf = fopen ( it - > first . c_str ( ) , " wb+ " ) ;
if ( pf )
{
fprintf ( pf , " %s, v1.0 \r \n %s,%04d-%02d-%02d,%02d \r \n " , it - > first . c_str ( ) , m_unit . name , system32 . now . year + 2000 , system32 . now . month , system32 . now . dayofmonth , m_information_address_length ) ;
fprintf ( pf , " %d,%s \r \n " , it - > second . count , it - > second . ss_outmax . c_str ( ) ) ;
fprintf ( pf , " %d,%s \r \n " , it - > second . count , it - > second . ss_outmin . c_str ( ) ) ;
fclose ( pf ) ;
}
}
}
catch ( SQLiteException & exception )
{
vLog ( LOG_ERROR , " \n Exception Occured " ) ;
exception . Show ( ) ;
vLog ( LOG_ERROR , " SQLite result code: %d,%s \n " , exception . GetSqliteResultCode ( ) , exception . GetErrorDescription ( ) . c_str ( ) ) ;
}
delete pStmt ;
}
void CGDW104FileProcess : : createYCHisRecordFile ( void )
{
int count = 0 ;
char query [ 512 ] ;
SQLiteStatement * pStmt = new SQLiteStatement ( & m_database ) ;
try
{
if ( m_bCallAllFile )
{
snprintf ( query , sizeof ( query ) , " SELECT * FROM YCHIS_RECORD_TABLE WHERE Ycdatetime %% 900 == 0; " ) ;
}
else
{
snprintf ( query , sizeof ( query ) , " SELECT * FROM YCHIS_RECORD_TABLE WHERE Ycdatetime >= %d AND Ycdatetime <= %d AND Ycdatetime %% 900 == 0; " , ( DWORD ) m_start_time , ( DWORD ) m_end_time ) ;
}
vLog ( LOG_DEBUG , " ychis file query is: %s \n " , query ) ;
std : : map < std : : string , STRUCT_FILEBUFFER > mapFixptFileBuffers ;
mapFixptFileBuffers . clear ( ) ;
pStmt - > BeginTransaction ( ) ;
pStmt - > Sql ( query ) ;
count = 0 ;
int max_count = mapYcExetremumRecordDatas . size ( ) ;
while ( pStmt - > FetchRow ( ) )
{
char buffer [ 256 ] ;
unionCP56Time ut = Time_ttounionCP56Time ( ( time_t ) pStmt - > GetColumnInt ( 1 ) ) ; //数据时间
snprintf ( buffer , sizeof ( buffer ) , FILE_FIXPT_PATH_NAME , str_fixptRecordDir . c_str ( ) , ut . year + 2000 , ut . month , ut . dayofmonth ) ;
std : : string filename = buffer ;
int point = pStmt - > GetColumnInt ( 0 ) ;
float fVal = pStmt - > GetColumnDouble ( 3 ) ;
snprintf ( buffer , sizeof ( buffer ) , " %4x,%4.3f " , point + m_yc_information_address_start , fVal ) ;
std : : string valbuffer = buffer ;
if ( mapFixptFileBuffers . find ( filename ) = = mapFixptFileBuffers . end ( ) )
{
char temp [ 64 ] ;
snprintf ( temp , sizeof ( temp ) , " %d,%04d-%02d-%02d %02d:%02d:%02d.%03d, " , max_count , ut . year + 2000 , ut . month , ut . dayofmonth , ut . hour , ut . minute , ut . millisecond / 1000 , ut . millisecond % 1000 ) ;
STRUCT_FILEBUFFER fb ;
fb . count = 1 ;
fb . ss_outmax = temp + valbuffer ;
mapFixptFileBuffers . insert ( std : : map < std : : string , STRUCT_FILEBUFFER > : : value_type ( filename , fb ) ) ;
}
else if ( count = = 0 )
{
char temp [ 64 ] ;
snprintf ( temp , sizeof ( temp ) , " %d,%04d-%02d-%02d %02d:%02d:%02d.%03d, " , max_count , ut . year + 2000 , ut . month , ut . dayofmonth , ut . hour , ut . minute , ut . millisecond / 1000 , ut . millisecond % 1000 ) ;
mapFixptFileBuffers [ filename ] . count + + ;
mapFixptFileBuffers [ filename ] . ss_outmax + = temp + valbuffer ;
}
else
{
mapFixptFileBuffers [ filename ] . ss_outmax + = " , " + valbuffer ;
}
count + + ;
if ( count > = max_count )
{
count = 0 ;
mapFixptFileBuffers [ filename ] . ss_outmax + = " \r \n " ;
}
}
pStmt - > FreeQuery ( ) ;
pStmt - > CommitTransaction ( ) ;
std : : map < std : : string , STRUCT_FILEBUFFER > : : iterator it ;
for ( it = mapFixptFileBuffers . begin ( ) ; it ! = mapFixptFileBuffers . end ( ) ; it + + )
{
FILE * pf = fopen ( it - > first . c_str ( ) , " wb+ " ) ;
if ( pf )
{
fprintf ( pf , " %s, v1.0 \r \n %s,%04d-%02d-%02d,%d,%02d \r \n " , it - > first . c_str ( ) , m_unit . name , system32 . now . year + 2000 , system32 . now . month , system32 . now . dayofmonth , it - > second . count , m_information_address_length ) ;
fprintf ( pf , " %s \r \n " , it - > second . ss_outmax . c_str ( ) ) ;
fclose ( pf ) ;
}
}
}
catch ( SQLiteException & exception )
{
vLog ( LOG_ERROR , " \n Exception Occured " ) ;
exception . Show ( ) ;
vLog ( LOG_ERROR , " SQLite result code: %d,%s \n " , exception . GetSqliteResultCode ( ) , exception . GetErrorDescription ( ) . c_str ( ) ) ;
}
delete pStmt ;
}
void CGDW104FileProcess : : createFmHisRecordFile ( void )
{
int count = 0 ;
char query [ 512 ] ;
SQLiteStatement * pStmt = new SQLiteStatement ( & m_database ) ;
try
{
if ( m_bCallAllFile )
{
snprintf ( query , sizeof ( query ) , " SELECT * FROM FMHIS_RECORD_TABLE WHERE Ymdatetime %% 900 == 0; " ) ;
}
else
{
snprintf ( query , sizeof ( query ) , " SELECT * FROM FMHIS_RECORD_TABLE WHERE Ymdatetime >= %d AND Ymdatetime <= %d AND Ymdatetime %% 900 == 0; " , ( DWORD ) m_start_time , ( DWORD ) m_end_time ) ;
}
vLog ( LOG_DEBUG , " create frz data query is: %s \n " , query ) ;
std : : map < std : : string , STRUCT_FILEBUFFER > mapFmHisFileBuffers ;
mapFmHisFileBuffers . clear ( ) ;
pStmt - > BeginTransaction ( ) ;
pStmt - > Sql ( query ) ;
count = 0 ;
while ( pStmt - > FetchRow ( ) )
{
char buffer [ 256 ] ;
unionCP56Time ut = Time_ttounionCP56Time ( ( time_t ) pStmt - > GetColumnInt ( 1 ) ) ; //数据时间
snprintf ( buffer , sizeof ( buffer ) , FILE_FRZ_PATH_NAME , str_frzRecordDir . c_str ( ) , ut . year + 2000 , ut . month , ut . dayofmonth ) ;
std : : string filename = buffer ;
int point = pStmt - > GetColumnInt ( 0 ) ;
float fVal = pStmt - > GetColumnDouble ( 3 ) ;
snprintf ( buffer , sizeof ( buffer ) , " %4x,%4.3f " , point + m_ym_information_address_start , fVal ) ;
std : : string valbuffer = buffer ;
if ( mapFmHisFileBuffers . find ( filename ) = = mapFmHisFileBuffers . end ( ) )
{
char temp [ 64 ] ;
snprintf ( temp , sizeof ( temp ) , " %d,%04d-%02d-%02d %02d:%02d:%02d.%03d, " , m_total_ym , ut . year + 2000 , ut . month , ut . dayofmonth , ut . hour , ut . minute , ut . millisecond / 1000 , ut . millisecond % 1000 ) ;
STRUCT_FILEBUFFER fb ;
fb . count = 1 ;
fb . ss_outmax = temp + valbuffer ;
mapFmHisFileBuffers . insert ( std : : map < std : : string , STRUCT_FILEBUFFER > : : value_type ( filename , fb ) ) ;
}
else if ( count = = 0 )
{
char temp [ 64 ] ;
snprintf ( temp , sizeof ( temp ) , " %d,%04d-%02d-%02d %02d:%02d:%02d.%03d, " , m_total_ym , ut . year + 2000 , ut . month , ut . dayofmonth , ut . hour , ut . minute , ut . millisecond / 1000 , ut . millisecond % 1000 ) ;
mapFmHisFileBuffers [ filename ] . count + + ;
mapFmHisFileBuffers [ filename ] . ss_outmax + = temp + valbuffer ;
}
else
{
mapFmHisFileBuffers [ filename ] . ss_outmax + = " , " + valbuffer ;
}
count + + ;
if ( count > = m_total_ym )
{
count = 0 ;
mapFmHisFileBuffers [ filename ] . ss_outmax + = " \r \n " ;
}
}
pStmt - > FreeQuery ( ) ;
pStmt - > CommitTransaction ( ) ;
std : : map < std : : string , STRUCT_FILEBUFFER > : : iterator it ;
for ( it = mapFmHisFileBuffers . begin ( ) ; it ! = mapFmHisFileBuffers . end ( ) ; it + + )
{
FILE * pf = fopen ( it - > first . c_str ( ) , " wb+ " ) ;
if ( pf )
{
fprintf ( pf , " %s, v1.0 \r \n %s,%04d-%02d-%02d,%d,%02d \r \n " , it - > first . c_str ( ) , m_unit . name , system32 . now . year + 2000 , system32 . now . month , system32 . now . dayofmonth , it - > second . count , m_information_address_length ) ;
fprintf ( pf , " %s \r \n " , it - > second . ss_outmax . c_str ( ) ) ;
fclose ( pf ) ;
}
}
}
catch ( SQLiteException & exception )
{
vLog ( LOG_ERROR , " \n Exception Occured " ) ;
exception . Show ( ) ;
vLog ( LOG_ERROR , " SQLite result code: %d,%s \n " , exception . GetSqliteResultCode ( ) , exception . GetErrorDescription ( ) . c_str ( ) ) ;
}
delete pStmt ;
}
void CGDW104FileProcess : : DumpSOE ( void )
{
if ( m_soe_load = = m_soe_save ) return ;
SQLiteStatement * pStmt = new SQLiteStatement ( & m_database ) ;
try
{
pStmt - > BeginTransaction ( ) ;
pStmt - > Sql ( " INSERT INTO SOE_RECORD_TABLE VALUES(?,?,?,?) " ) ;
//保存SOE数据
while ( m_soe_load ! = m_soe_save )
{
pStmt - > BindInt ( 1 , m_soes [ m_soe_load ] . order ) ;
pStmt - > BindInt ( 2 , m_soes [ m_soe_load ] . value ) ;
pStmt - > BindInt ( 3 , unionCP56TimetoTime_t ( & m_soes [ m_soe_load ] . st ) ) ;
pStmt - > BindInt ( 4 , ( m_soes [ m_soe_load ] . st . millisecond % 1000 ) ) ;
pStmt - > Execute ( ) ;
pStmt - > Reset ( ) ;
m_soe_load + + ;
m_soe_load = m_soe_load % DATABASE_SOE_NUM ;
}
pStmt - > FreeQuery ( ) ;
pStmt - > CommitTransaction ( ) ;
}
catch ( SQLiteException & exception )
{
vLog ( LOG_ERROR , " \n Exception Occured " ) ;
exception . Show ( ) ;
vLog ( LOG_ERROR , " SQLite result code: %d,%s \n " , exception . GetSqliteResultCode ( ) , exception . GetErrorDescription ( ) . c_str ( ) ) ;
}
delete pStmt ;
}
void CGDW104FileProcess : : DumpYKLog ( void )
{
if ( m_yklog_load = = m_yklog_save ) return ;
SQLiteStatement * pStmt = new SQLiteStatement ( & m_database ) ;
try
{
pStmt - > BeginTransaction ( ) ;
pStmt - > Sql ( " INSERT INTO YKLOG_RECORD_TABLE VALUES(?,?,?,?,?) " ) ;
//保存SOE数据
while ( m_yklog_load ! = m_yklog_save )
{
pStmt - > BindInt ( 1 , m_yklogs [ m_yklog_load ] . point ) ;
pStmt - > BindInt ( 2 , m_yklogs [ m_yklog_load ] . type ) ;
pStmt - > BindInt ( 3 , m_yklogs [ m_yklog_load ] . value ) ;
pStmt - > BindInt ( 4 , unionCP56TimetoTime_t ( & m_yklogs [ m_yklog_load ] . st ) ) ;
pStmt - > BindInt ( 5 , ( m_yklogs [ m_yklog_load ] . st . millisecond % 1000 ) ) ;
pStmt - > Execute ( ) ;
pStmt - > Reset ( ) ;
m_yklog_load + + ;
m_yklog_load = m_yklog_load % DATABASE_YK_LOG_NUM ;
}
pStmt - > FreeQuery ( ) ;
pStmt - > CommitTransaction ( ) ;
}
catch ( SQLiteException & exception )
{
vLog ( LOG_ERROR , " \n Exception Occured " ) ;
exception . Show ( ) ;
vLog ( LOG_ERROR , " SQLite result code: %d,%s \n " , exception . GetSqliteResultCode ( ) , exception . GetErrorDescription ( ) . c_str ( ) ) ;
}
delete pStmt ;
}
void CGDW104FileProcess : : UpdateExtremumRecord ( BOOLEAN bAddNew )
{
SQLiteStatement * pStmt = new SQLiteStatement ( & m_database ) ;
try
{
pStmt - > BeginTransaction ( ) ;
if ( bAddNew )
{
pStmt - > Sql ( " INSERT INTO YCEXV_RECORD_TABLE VALUES(?,?,?,?,?,?,?,?) " ) ;
//保存极值数据
std : : map < int , STRUCT_YCEXTREMUM > : : iterator it ;
for ( it = mapYcExetremumRecordDatas . begin ( ) ; it ! = mapYcExetremumRecordDatas . end ( ) ; it + + )
{
pStmt - > BindInt ( 1 , it - > first ) ;
//将数据都更新为当前数据和当前时间
it - > second . datetime = system32 . timers ;
it - > second . iMaxVal = it - > second . iCurVal ;
it - > second . iMinVal = it - > second . iCurVal ;
it - > second . fMaxVal = it - > second . iCurVal * it - > second . fCoef + it - > second . fBase ;
it - > second . fMinVal = it - > second . iCurVal * it - > second . fCoef + it - > second . fBase ;
it - > second . MaxTime = system32 . timers ;
it - > second . MinTime = system32 . timers ;
pStmt - > BindInt ( 2 , ( LONG ) it - > second . datetime ) ;
pStmt - > BindInt ( 3 , it - > second . iMaxVal ) ;
pStmt - > BindInt ( 4 , it - > second . iMinVal ) ;
pStmt - > BindDouble ( 5 , it - > second . fMaxVal ) ;
pStmt - > BindDouble ( 6 , it - > second . fMinVal ) ;
pStmt - > BindInt ( 7 , ( LONG ) it - > second . MaxTime ) ;
pStmt - > BindInt ( 8 , ( LONG ) it - > second . MinTime ) ;
pStmt - > Execute ( ) ;
pStmt - > Reset ( ) ;
}
}
else
{
pStmt - > Sql ( " UPDATE YCEXV_RECORD_TABLE SET "
" YciMaxval=@YciMaxval, "
" YciMinval=@YciMinval, "
" YcfMaxval=@YcfMaxval, "
" YcfMinval=@YcfMinval, "
" YcMaxdatetime=@YcMaxdatetime, "
" YcMindatetime=@YcMindatetime "
" WHERE Ycpoint=@Ycpoint " ) ;
//保存极值数据
std : : map < int , STRUCT_YCEXTREMUM > : : iterator it ;
for ( it = mapYcExetremumRecordDatas . begin ( ) ; it ! = mapYcExetremumRecordDatas . end ( ) ; it + + )
{
pStmt - > BindInt ( 1 , it - > second . iMaxVal ) ;
pStmt - > BindInt ( 2 , it - > second . iMinVal ) ;
pStmt - > BindDouble ( 3 , it - > second . fMaxVal ) ;
pStmt - > BindDouble ( 4 , it - > second . fMinVal ) ;
pStmt - > BindInt ( 5 , ( LONG ) it - > second . MaxTime ) ;
pStmt - > BindInt ( 6 , ( LONG ) it - > second . MinTime ) ;
pStmt - > BindInt ( 7 , it - > first ) ;
pStmt - > Execute ( ) ;
pStmt - > Reset ( ) ;
}
}
pStmt - > FreeQuery ( ) ;
pStmt - > CommitTransaction ( ) ;
}
catch ( SQLiteException & exception )
{
vLog ( LOG_ERROR , " \n Exception Occured " ) ;
exception . Show ( ) ;
vLog ( LOG_ERROR , " aaaaSQLite result code: %d,%s \n " , exception . GetSqliteResultCode ( ) , exception . GetErrorDescription ( ) . c_str ( ) ) ;
}
delete pStmt ;
}
void CGDW104FileProcess : : DumpYCHisRecord ( LONG now )
{
SQLiteStatement * pStmt = new SQLiteStatement ( & m_database ) ;
try
{
pStmt - > BeginTransaction ( ) ;
pStmt - > Sql ( " INSERT INTO YCHIS_RECORD_TABLE VALUES(?,?,?,?) " ) ;
std : : map < int , STRUCT_YCEXTREMUM > : : iterator it ;
for ( it = mapYcExetremumRecordDatas . begin ( ) ; it ! = mapYcExetremumRecordDatas . end ( ) ; it + + )
{
pStmt - > BindInt ( 1 , it - > first ) ;
pStmt - > BindInt ( 2 , now ) ;
pStmt - > BindInt ( 3 , it - > second . iCurVal ) ;
pStmt - > BindDouble ( 4 , ( ( it - > second . iCurVal * it - > second . fCoef ) + it - > second . fBase ) ) ;
pStmt - > Execute ( ) ;
pStmt - > Reset ( ) ;
}
pStmt - > FreeQuery ( ) ;
pStmt - > CommitTransaction ( ) ;
}
catch ( SQLiteException & exception )
{
vLog ( LOG_ERROR , " \n Exception Occured " ) ;
exception . Show ( ) ;
vLog ( LOG_ERROR , " SQLite result code: %d,%s \n " , exception . GetSqliteResultCode ( ) , exception . GetErrorDescription ( ) . c_str ( ) ) ;
}
delete pStmt ;
}
void CGDW104FileProcess : : DumpFmHisRecord ( LONG now )
{
SQLiteStatement * pStmt = new SQLiteStatement ( & m_database ) ;
try
{
pStmt - > BeginTransaction ( ) ;
//pStmt->Sql("INSERT INTO FMHIS_RECORD_TABLE VALUES(?,?,?,?)");
pStmt - > Sql ( " REPLACE INTO FMHIS_RECORD_TABLE VALUES(?,?,?,?) " ) ;
for ( int i = 0 ; i < m_total_ym ; i + + )
{
pStmt - > BindInt ( 1 , m_pUnitYM [ i ] . order ) ;
pStmt - > BindInt ( 2 , now ) ;
pStmt - > BindInt ( 3 , m_pUnitYM [ i ] . value ) ;
pStmt - > BindDouble ( 4 , ( ( m_pUnitYM [ i ] . value * m_pUnitYM [ i ] . coef ) + m_pUnitYM [ i ] . base ) ) ;
pStmt - > Execute ( ) ;
pStmt - > Reset ( ) ;
}
pStmt - > FreeQuery ( ) ;
pStmt - > CommitTransaction ( ) ;
}
catch ( SQLiteException & exception )
{
vLog ( LOG_ERROR , " \n Exception Occured " ) ;
exception . Show ( ) ;
vLog ( LOG_ERROR , " SQLite result code: %d,%s \n " , exception . GetSqliteResultCode ( ) , exception . GetErrorDescription ( ) . c_str ( ) ) ;
}
delete pStmt ;
}
CSubGDW104Process : : CSubGDW104Process ( )
{
last_sec = system32 . timers ;
m_dwFileType = 0 ;
memset ( & m_nOption , 0 , sizeof ( m_nOption ) ) ;
}
CSubGDW104Process : : ~ CSubGDW104Process ( )
{
}
BOOLEAN CSubGDW104Process : : OnPreCreate ( int id )
{
if ( ! CIEC104Process : : OnPreCreate ( id ) ) return FALSE ;
m_yx_start_address = m_nOption . yx_start_address ;
m_yc_start_address = m_nOption . yc_start_address ;
m_ym_start_address = m_nOption . ym_start_address ;
if ( m_yx_start_address < = 0 ) m_yx_start_address = IEC_101_104_YX_START_ADDR ;
if ( m_yc_start_address < = 0 ) m_yc_start_address = IEC_101_104_YC_START_ADDR ;
if ( m_ym_start_address < = 0 ) m_ym_start_address = IEC_101_104_YM_START_ADDR ;
if ( ! GetOption ( & gdw_option , sizeof ( gdw_option ) ) )
{
return FALSE ;
}
int i ;
int uid ;
CIEC104ProcessItem * pItem ;
//更新配置
for ( i = 0 ; i < PROCESS_UNIT_NUM ; i + + )
{
pItem = ( CIEC104ProcessItem * ) GetItem ( i ) ;
if ( NULL = = pItem ) continue ;
pItem - > apdu_k_max = m_nOption . k ;
pItem - > apdu_w_max = m_nOption . w ;
pItem - > apdu_t0_begin = 10 ;
uid = GetUnitID ( i ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) continue ;
m_gdwFile . OnCreate ( uid , & config . units [ uid ] , & gdw_option ) ;
}
return TRUE ;
}
BOOLEAN CSubGDW104Process : : OnCreated ( int id )
{
pthread_attr_t attr ;
pthread_attr_init ( & attr ) ;
pthread_attr_setstacksize ( & attr , MEMERY_1M ) ;
pthread_attr_setdetachstate ( & attr , PTHREAD_CREATE_DETACHED ) ;
pthread_t pid ;
if ( pthread_create ( & pid , & attr , main_file_process , & m_gdwFile ) < 0 )
{
vLog ( LOG_ERROR , " create main_run_process error(%d,%s). \n " , errno , strerror ( errno ) ) ;
return FALSE ;
}
pthread_attr_destroy ( & attr ) ;
return CIEC104Process : : OnCreated ( id ) ;
}
void CSubGDW104Process : : GetItemEvents ( CIEC104ProcessItem * pItem )
{
int i , uid , count ;
int soe_point ;
BOOLEAN soe_value ;
BYTE soe_qds ;
unionCP56Time soe_time ;
if ( NULL = = pItem ) return ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return ;
if ( NULL = = pItem - > events . data ) return ;
count = pItem - > events . count ;
if ( count < 0 | | count > = DATABASE_SOE_NUM ) count = 0 ;
int max_count = DATABASE_SOE_NUM - count ;
for ( i = 0 ; i < max_count ; i + + )
{
soe_point = GetUnitSOE ( uid , soe_value , soe_qds , soe_time ) ;
if ( soe_point < 0 ) break ;
pItem - > events . data [ count ] . order = soe_point ;
pItem - > events . data [ count ] . value = soe_value ;
pItem - > events . data [ count ] . qds = soe_qds ;
memcpy ( & pItem - > events . data [ count ] . ct , & soe_time , sizeof ( soe_time ) ) ;
m_gdwFile . PushSOE ( soe_time , soe_point , soe_value , uid ) ;
count + + ;
}
pItem - > events . count = count ;
}
BOOLEAN CSubGDW104Process : : FetchUnitYC ( int order )
{
int i ;
int uid ;
int oid ;
struUnit * pUnit ;
if ( order < 0 | | order > = PROCESS_UNIT_NUM ) return FALSE ;
uid = config . processes [ m_nProcess ] . units [ order ] ;
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
pUnit = & config . units [ uid ] ;
if ( ( pUnit - > state & 0x01 ) ! = TRUE ) return FALSE ;
for ( i = 0 ; i < pUnit - > yccount ; i + + )
{
oid = pUnit - > ycs [ i ] . order ;
if ( oid < 0 | | oid > = DATABASE_YC_NUM ) continue ;
pUnit - > ycs [ i ] . qds = database . ycs [ oid ] . qds ;
if ( pUnit - > ycs [ i ] . value ! = database . ycs [ oid ] . value )
{ //此处家里如极值判断,并入库
if ( pUnit - > ycs [ i ] . change_pos > = 0 )
{
if ( abs ( pUnit - > ycs [ i ] . value - database . ycs [ oid ] . value ) > = pUnit - > ycs [ i ] . change_pos )
{ //40码值变化量认为是遥测变位
pUnit - > ycs [ i ] . value = database . ycs [ oid ] . value ;
pUnit - > ycs [ i ] . update_time = database . ycs [ oid ] . update_time ;
pUnit - > ycs [ i ] . ycbw = TRUE ;
}
}
}
m_gdwFile . AddExtremumRecord ( i , database . ycs [ oid ] . value ) ;
}
return TRUE ;
}
BOOLEAN CSubGDW104Process : : FetchUnitYM ( int order )
{
int i ;
int uid ;
int oid ;
struUnit * pUnit ;
if ( order < 0 | | order > = PROCESS_UNIT_NUM ) return FALSE ;
uid = config . processes [ m_nProcess ] . units [ order ] ;
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
pUnit = & config . units [ uid ] ;
if ( ( pUnit - > state & 0x01 ) ! = TRUE ) return FALSE ;
for ( i = 0 ; i < pUnit - > ymcount ; i + + )
{
oid = pUnit - > yms [ i ] . order ;
if ( oid < 0 | | oid > = DATABASE_YM_NUM ) continue ;
if ( pUnit - > yms [ i ] . value ! = database . yms [ oid ] . value )
{
pUnit - > yms [ i ] . value = database . yms [ oid ] . value ;
pUnit - > yms [ i ] . update_time = database . yms [ oid ] . update_time ;
}
}
m_gdwFile . AddFmRecord ( pUnit - > yms , pUnit - > ymcount ) ;
return TRUE ;
}
BOOLEAN CSubGDW104Process : : Run ( void )
{
if ( ! CIEC104Process : : Run ( ) ) return FALSE ;
int i , uid ;
CIEC104ProcessItem * pItem ;
FeedDog ( ) ;
for ( i = 0 ; i < PROCESS_UNIT_NUM ; i + + )
{
pItem = ( CIEC104ProcessItem * ) GetItem ( i ) ;
if ( NULL = = pItem ) continue ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) continue ;
if ( pItem - > interrogation_finish )
{
GetItemYXBWs ( pItem ) ;
}
//刷新事件记录库
GetItemEvents ( pItem ) ;
//刷新遥测库
FetchUnitYC ( i ) ;
//刷新遥脉库
FetchUnitYM ( i ) ;
//总召唤结束,开始刷新遥测变位缓冲。
if ( pItem - > interrogation_finish )
{ //刷新遥测变位
if ( pItem - > ycbws . count < = 0 )
{ //当遥测变位发送结束后才更新
GetItemYCBWs ( pItem ) ;
}
}
}
return TRUE ;
}
BOOLEAN CSubGDW104Process : : OnTimer ( void )
{
int uid ;
int i ;
int ret ;
CIEC104ProcessItem * pItem ;
BOOLEAN sec_changed = FALSE ;
if ( ! CIEC104Process : : OnTimer ( ) ) return FALSE ;
//是否发生了秒变化
if ( last_sec ! = ( time_t ) system32 . timers )
{
last_sec = system32 . timers ;
sec_changed = TRUE ;
}
for ( i = 0 ; i < PROCESS_UNIT_NUM ; i + + )
{
pItem = ( CIEC104ProcessItem * ) GetItem ( i ) ;
if ( NULL = = pItem ) continue ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) continue ;
if ( pItem - > GetSock ( ) < 0 )
{
continue ;
}
pItem - > apdu_t0_begin = system32 . timers ;
//判断t3超时
if ( pItem - > apdu_t3_begin > 0 & & system32 . timers > ( pItem - > apdu_t3_begin + apdu_t3_max ) )
{
if ( ! SendUFrame ( FALSE , FALSE , FALSE , FALSE , TRUE , FALSE , i ) )
{
vLog ( LOG_ERROR , " Unit(%d) SendUFrame error. \n " , uid ) ;
pItem - > Release ( ) ;
continue ;
}
pItem - > apdu_t3_begin = 0 ;
//启动t1计时
pItem - > apdu_t1_begin = system32 . timers ;
pItem - > apdu_wait_test = TRUE ;
continue ;
}
//判断t1超时
if ( pItem - > apdu_t1_begin > 0 & & system32 . timers > ( pItem - > apdu_t1_begin + apdu_t1_max ) )
{ //直接复位链路
vLog ( LOG_ERROR , " Unit(%d) t1 expired (begin at %lu). \n " , uid , pItem - > apdu_t1_begin ) ;
pItem - > Release ( ) ;
continue ;
}
//判断t2超时
if ( pItem - > apdu_t2_begin > 0 & & system32 . timers > ( pItem - > apdu_t2_begin + apdu_t2_max ) )
{ //发送S帧
if ( ! SendSFrame ( i ) )
{
vLog ( LOG_ERROR , " Unit(%d) SendSFrame error. \n " , uid ) ;
pItem - > Release ( ) ;
continue ;
}
continue ;
}
//如果链路通信未启动则不发送任何报文
if ( ! pItem - > apdu_setup ) continue ;
//是否已经达到k值,若k值已经达到则不再发送数据报文
if ( pItem - > apdu_k > = pItem - > apdu_k_max ) continue ;
//总召唤没有结束, 不响应遥控。不上送遥信变位及SOE
if ( pItem - > interrogation_finish )
{ //发送遥控返校
ret = MakeYKFrame ( pItem , i ) ;
if ( ret < 0 )
{
pItem - > Release ( ) ;
continue ;
}
else if ( ret > 0 ) continue ;
//发送遥调返校
ret = MakeYTFrame ( pItem , i ) ;
if ( ret < 0 )
{
pItem - > Release ( ) ;
continue ;
}
else if ( ret > 0 ) continue ;
//发送遥信变位
ret = Send_Single_point_information ( pItem , i ) ;
if ( ret < 0 )
{
pItem - > Release ( ) ;
continue ;
}
else if ( ret > 0 ) continue ;
//发送SOE信息
ret = Send_Single_point_information_with_time_tag_cp56time2a ( pItem , i ) ;
if ( ret < 0 )
{
pItem - > Release ( ) ;
continue ;
}
else if ( ret > 0 ) continue ;
}
//响应总召唤命令
if ( pItem - > interrogation_start )
{
2024-09-24 15:59:22 +08:00
if ( pItem - > interrogation_type ! = IEC_101_104_COT_INTERROGATION )
2024-07-08 10:27:17 +08:00
{ //组召唤
//激活终止
ret = Send_FrameInterrogation ( pItem , i ) ;
if ( ret < 0 )
{
vLog ( LOG_ERROR , " Unit(%d) Send_FrameInterrogation error. \n " , uid ) ;
pItem - > Release ( ) ;
continue ;
}
else if ( ret > 0 )
{
2024-09-24 15:59:22 +08:00
pItem - > interrogation_type = 0 ;
2024-07-08 10:27:17 +08:00
pItem - > interrogation_finish = TRUE ;
pItem - > interrogation_start = FALSE ;
pItem - > interrogation_yx_fin = TRUE ;
pItem - > interrogation_yc_fin = TRUE ;
continue ;
}
}
if ( ! pItem - > interrogation_yx_fin )
{
ret = Send_Single_point_information ( pItem , i , IEC_101_104_COT_INTERROGATION ) ;
if ( ret < 0 )
{
vLog ( LOG_ERROR , " Unit(%d) Send_Single_point_information IEC_101_104_COT_INTERROGATION error. \n " , uid ) ;
pItem - > Release ( ) ;
continue ;
}
else if ( ret > 0 ) continue ;
}
if ( ! pItem - > interrogation_yc_fin )
{
switch ( m_nOption . yc_type )
{
case USE_YC_NB : //标度化值
ret = Send_Measured_value_scaled ( pItem , i , IEC_101_104_COT_INTERROGATION ) ;
break ;
case USE_YC_NC : //短浮点数
ret = Send_Measured_value_short_floating_point ( pItem , i , IEC_101_104_COT_INTERROGATION ) ;
break ;
case USE_YC_ND : //不带品质归一化值
ret = Send_Measured_value_normalised_without_quality ( pItem , i , IEC_101_104_COT_INTERROGATION ) ;
break ;
default : //USE_YC_NA: 归一化值
ret = Send_Measured_value_normalised ( pItem , i , IEC_101_104_COT_INTERROGATION ) ;
break ;
}
if ( ret < 0 )
{
vLog ( LOG_ERROR , " Unit(%d) Send_Measured_value IEC_101_104_COT_INTERROGATION error. \n " , uid ) ;
pItem - > Release ( ) ;
continue ;
}
else if ( ret > 0 ) continue ;
}
//激活终止
ret = Send_FrameInterrogation ( pItem , i ) ;
if ( ret < 0 )
{
vLog ( LOG_ERROR , " Unit(%d) Send_FrameInterrogation error. \n " , uid ) ;
pItem - > Release ( ) ;
continue ;
}
else if ( ret > 0 )
{
2024-09-24 15:59:22 +08:00
pItem - > interrogation_type = 0 ;
2024-07-08 10:27:17 +08:00
pItem - > interrogation_finish = TRUE ;
pItem - > interrogation_start = FALSE ;
pItem - > interrogation_yx_fin = TRUE ;
pItem - > interrogation_yc_fin = TRUE ;
continue ;
}
}
//响应召唤电能脉冲
if ( pItem - > pulse_start )
{
if ( ! pItem - > pulse_fin )
{
ret = Send_Integrated_totals ( pItem , i , IEC_101_104_COT_REQCOGEN ) ;
if ( ret < 0 )
{
vLog ( LOG_ERROR , " Unit(%d) Send_Integrated_totals error. \n " , uid ) ;
pItem - > Release ( ) ;
continue ;
}
else if ( ret > 0 ) continue ;
}
//激活终止
ret = Send_FrameCounterInterrogation ( pItem , i ) ;
if ( ret < 0 )
{
vLog ( LOG_ERROR , " Unit(%d) Send_FrameCounterInterrogation error. \n " , uid ) ;
pItem - > Release ( ) ;
continue ;
}
else if ( ret > 0 )
{
2024-09-24 15:59:22 +08:00
pItem - > pulse_type = 0 ;
2024-07-08 10:27:17 +08:00
pItem - > pulse_start = FALSE ;
pItem - > pulse_fin = TRUE ;
continue ;
}
}
//文件
ret = MakeFileFrame ( pItem , i ) ;
if ( ret < 0 )
{
pItem - > Release ( ) ;
continue ;
}
else if ( ret > 0 )
{
vLog ( LOG_DEBUG , " here......MakeFileFrame. \n " ) ;
continue ;
}
//总召唤没有结束,不上送变位遥测
if ( pItem - > interrogation_finish )
{ //发送遥测变位
if ( sec_changed )
{
switch ( m_nOption . yc_type )
{
case USE_YC_NB : //标度化值
ret = Send_Measured_value_scaled ( pItem , i ) ;
break ;
case USE_YC_NC : //短浮点数
ret = Send_Measured_value_short_floating_point ( pItem , i ) ;
break ;
case USE_YC_ND : //不带品质归一化值
ret = Send_Measured_value_normalised_without_quality ( pItem , i ) ;
break ;
default : //USE_YC_NA: 归一化值
ret = Send_Measured_value_normalised ( pItem , i ) ;
break ;
}
if ( ret < 0 )
{
vLog ( LOG_ERROR , " Unit(%d) Send_Measured_value IEC_101_104_COT_SPONT error. \n " , uid ) ;
pItem - > Release ( ) ;
continue ;
}
else if ( ret > 0 ) continue ;
}
}
}
return TRUE ;
}
BOOLEAN CSubGDW104Process : : OnIFrameReceived ( WORD ns , WORD nr , BYTE * pBuf , int count , int ord )
{
int uid ;
CIEC104ProcessItem * pItem = ( CIEC104ProcessItem * ) GetItem ( ord ) ;
if ( NULL = = pItem ) return FALSE ;
uid = ( int ) pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
//处理接收序号
if ( ! OnDealWithPeerNS ( pItem , ns ) ) return FALSE ;
//处理发送序号
if ( ! OnDealWithPeerNR ( pItem , nr ) ) return FALSE ;
//启动t2计时
if ( pItem - > apdu_t2_begin = = 0 )
{
pItem - > apdu_t2_begin = system32 . timers ;
}
pItem - > apdu_w + + ;
if ( pItem - > apdu_w > = pItem - > apdu_w_max )
{
if ( ! SendSFrame ( ord ) ) return FALSE ;
}
//重置t3计时
pItem - > apdu_t3_begin = system32 . timers ;
//处理接收到的报文
int ret ;
int len ;
BYTE buffer [ 256 ] ;
BYTE * pData = pBuf ;
BYTE TI ;
// BYTE VSQ;
WORD COT ;
BYTE cause_of_transmission ;
TI = * pData ; pData + + ;
//VSQ = *pData;
pData + + ;
COT = GetCOT ( pData ) ; pData + = cot_length ;
//判断CA地址是否正确
short apdu_addr = GetAsduAddr ( pData ) ; pData + = asdu_addr_length ;
if ( apdu_addr ! = pItem - > apdu_addr )
{
vLog ( LOG_WARN , " Unit(%d) invalid CA(%d) received. \n " , uid , apdu_addr ) ;
return FALSE ;
}
cause_of_transmission = GET_COT ( COT ) ;
len = 0 ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
switch ( TI )
{
case C_IC_NA_1 : //总召唤命令
ret = Receive_Interrogation_command ( pItem , pData , cause_of_transmission , buffer , len ) ;
if ( NO_ERROR = = ret )
{
pItem - > interrogation_start = TRUE ;
pItem - > interrogation_yx_fin = FALSE ;
pItem - > interrogation_yc_fin = FALSE ;
pItem - > yx_pos = 0 ;
pItem - > yc_pos = 0 ;
//清空原先YXBW库
ClearUnitYXBW ( uid ) ;
}
break ;
case C_SC_NA_1 : //单点遥控命令.没有总召唤,不响应遥控报文
if ( ! pItem - > interrogation_finish ) return TRUE ;
ret = Receive_Single_command ( pItem , pData , cause_of_transmission , buffer , len ) ;
break ;
case C_DC_NA_1 : //双点遥控命令.没有总召唤,不响应遥控报文
if ( ! pItem - > interrogation_finish ) return TRUE ;
ret = Receive_Double_command ( pItem , pData , cause_of_transmission , buffer , len ) ;
break ;
case C_CI_NA_1 : //脉冲量召唤命令
Receive_Counter_interrogation_command ( pItem , pData , cause_of_transmission , buffer , len ) ;
break ;
case C_CS_NA_1 : //时间同步命令
Receive_Clock_synchronisation_command ( pItem , pData , cause_of_transmission , buffer , len ) ;
break ;
case C_SE_NA_1 : //设定命令,归一化值.没有总召唤,不响应设定报文
if ( ! pItem - > interrogation_finish ) return TRUE ;
Receive_Set_point_command_normalized ( pItem , pData , cause_of_transmission , buffer , len ) ; //设定规一化值命令
break ;
case C_SE_NB_1 : //设定命令,标度化值.没有总召唤,不响应设定报文
if ( ! pItem - > interrogation_finish ) return TRUE ;
Receive_Set_point_command_scaled ( pItem , pData , cause_of_transmission , buffer , len ) ; //设定标度化值命令
break ;
case C_SE_NC_1 : //设定命令,短浮点数.没有总召唤,不响应设定报文
if ( ! pItem - > interrogation_finish ) return TRUE ;
Receive_Set_point_command_short_floating ( pItem , pData , cause_of_transmission , buffer , len ) ; //设定短浮点值命令
break ;
case GDW_F_FR_NA_1 :
Receive_FileTrans ( pItem , pData , cause_of_transmission ) ;
break ;
default :
vLog ( LOG_WARN , " Unit(%d) Unsupported I frame type = 0x%02x \n " , uid , ( int ) pBuf [ 0 ] ) ;
len = count ;
memcpy ( buffer , pBuf , count ) ;
buffer [ 1 ] = 1 ;
SetCOT ( & buffer [ 2 ] , ( IEC_101_104_COT_UNKNOWN_TI | IEC_101_104_COT_PN ) ) ;
}
if ( len )
{
return SendIFrame ( buffer , len , ord ) ;
}
return TRUE ;
}
BOOLEAN CSubGDW104Process : : OnUFrameReceived ( BOOLEAN STARTDT_ACT , BOOLEAN STARTDT_CON , BOOLEAN STOPDT_ACT , BOOLEAN STOPDT_CON , BOOLEAN TESTFR_ACT , BOOLEAN TESTFR_CON , int ord )
{
int uid ;
BYTE phy_addr [ 6 ] ;
CIEC104ProcessItem * pItem = ( CIEC104ProcessItem * ) GetItem ( ord ) ;
if ( NULL = = pItem ) return FALSE ;
uid = ( int ) pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
vLog ( LOG_DEBUG , " Unit(%d) Received U Frame%s%s%s%s%s%s \n " ,
uid ,
( STARTDT_ACT ? " STARTDT active " : " " ) ,
( STOPDT_ACT ? " STOPDT active " : " " ) ,
( TESTFR_ACT ? " TESTFR active " : " " ) ,
( STARTDT_CON ? " STARTDT confirm " : " " ) ,
( STOPDT_CON ? " STOPDT confirm " : " " ) ,
( TESTFR_CON ? " TESTFR confirm " : " " ) ) ;
if ( STARTDT_ACT )
{
if ( ! SendUFrame ( FALSE , TRUE , FALSE , FALSE , FALSE , FALSE , ord ) ) return FALSE ;
//链路链接建立
if ( ! GetUnitAddr ( uid , ( BYTE * ) phy_addr , 6 ) )
{
pItem - > apdu_addr = 0x0001 ;
}
else
{
pItem - > apdu_addr = ( ( phy_addr [ 5 ] < < 8 ) | phy_addr [ 4 ] ) ;
}
vLog ( LOG_DEBUG , " Unit(%d) apdu_addr(%d) \n " , uid , pItem - > apdu_addr ) ;
pItem - > apdu_setup = TRUE ;
pItem - > apdu_ns = 0 ;
pItem - > apdu_nr = 0 ;
pItem - > apdu_ack = 0 ;
pItem - > apdu_t3_begin = system32 . timers ; //启动t3计时
pItem - > apdu_wait_test = FALSE ;
pItem - > apdu_k = 0 ;
pItem - > interrogation_start = FALSE ;
pItem - > interrogation_yx_fin = FALSE ;
pItem - > interrogation_yc_fin = FALSE ;
pItem - > total_yx = GetUnitYXCount ( uid ) ;
vLog ( LOG_DEBUG , " Unit(%d) total yx count is %d. \n " , uid , pItem - > total_yx ) ;
pItem - > total_yc = GetUnitYCCount ( uid ) ;
vLog ( LOG_DEBUG , " Unit(%d) total yc count is %d. \n " , uid , pItem - > total_yc ) ;
pItem - > total_ym = GetUnitYMCount ( uid ) ;
vLog ( LOG_DEBUG , " Unit(%d) total ym count is %d. \n " , uid , pItem - > total_ym ) ;
pItem - > yx_pos = 0 ;
pItem - > yc_pos = 0 ;
pItem - > ym_pos = 0 ;
//初始化结束帧
if ( ! pItem - > end_of_initialisation )
{
pItem - > end_of_initialisation = TRUE ;
if ( ! Send_End_of_initialisation ( pItem , ord ) ) return FALSE ;
}
}
if ( STARTDT_CON )
{
vLog ( LOG_WARN , " UNSUPPORT STARTDT CONFIRM! Disconnect link! \n " ) ;
pItem - > Release ( ) ;
return FALSE ;
}
if ( STOPDT_ACT )
{
vLog ( LOG_WARN , " UNSUPPORT STOPDT COMMAND! Disconnect link! \n " ) ;
pItem - > Release ( ) ;
return FALSE ;
}
if ( STOPDT_CON )
{
vLog ( LOG_WARN , " UNSUPPORT STOPDT CONFIRM! Disconnect link! \n " ) ;
pItem - > Release ( ) ;
return FALSE ;
}
if ( TESTFR_ACT )
{
if ( ! SendUFrame ( FALSE , FALSE , FALSE , FALSE , FALSE , TRUE , ord ) )
{
vLog ( LOG_WARN , " Send U Frame Error. \n " ) ;
pItem - > Release ( ) ;
return FALSE ;
}
pItem - > apdu_t1_begin = 0 ;
pItem - > apdu_t3_begin = system32 . timers ; //重置t3计时
}
if ( TESTFR_CON )
{
if ( pItem - > apdu_wait_test )
{
pItem - > apdu_t1_begin = 0 ;
pItem - > apdu_t3_begin = system32 . timers ; //重置t3计时
pItem - > apdu_wait_test = FALSE ;
}
else
{
vLog ( LOG_WARN , " UNSUPPORT TESTFR CONFIRM! Disconnect link! \n " ) ;
pItem - > Release ( ) ;
return FALSE ;
}
}
return TRUE ;
}
int CSubGDW104Process : : MakeYKFrame ( CIEC104ProcessItem * pItem , int ord )
{
BYTE buffer [ 32 ] ;
if ( NULL = = pItem ) return - 1 ;
int order ;
BYTE value , action , result ;
if ( ! GetUnitYK ( pItem - > GetUnitID ( ) , order , value , action , result ) )
{
return 0 ;
}
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is %s result is %s \n " , pItem - > GetUnitID ( ) , order , ( value ? " CLOSE " : " TRIP " ) , val_to_str ( action , yk_state , " STATE=%d " ) , val_to_str ( result , yk_result , " RESULT=%d " ) ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
if ( YKS_SELED = = action & & YKR_FAIL = = result )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] | = IEC_101_104_SE ;
action = YKS_ABRED ;
}
else if ( YKS_SELREQ = = action & & YKR_OVER = = result )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] | = IEC_101_104_SE ;
action = YKS_ABRED ;
}
else if ( YKS_SELING = = action & & YKR_OVER = = result )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] | = IEC_101_104_SE ;
action = YKS_ABRED ;
}
BYTE * param ;
BOOLEAN yk_type ;
//BYTE relay_type;
DWORD ioa ;
param = GetUnitYKParamByPoint ( pItem - > GetUnitID ( ) , order ) ;
ioa = MAKEDWORD ( MAKEWORD ( param [ 0 ] , param [ 1 ] ) , MAKEWORD ( param [ 2 ] , param [ 3 ] ) ) ;
yk_type = param [ 4 ] ;
//relay_type = param[5];
if ( yk_type = = USE_YK_DC | | yk_type = = USE_YK_DEF )
{ //双点遥控
buffer [ 0 ] = C_DC_NA_1 ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] | = value ? DCO_ON : DCO_OFF ;
}
else
{
buffer [ 0 ] = C_SC_NA_1 ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] | = value ? SCO_ON : SCO_OFF ;
}
buffer [ 1 ] = 1 ;
if ( YKS_SELED = = action )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] | = IEC_101_104_SE ;
SetCOT ( & buffer [ 2 ] , IEC_101_104_COT_ACTCON ) ;
m_gdwFile . PushYKLog ( system32 . now , ioa , value , YKT_SELRET , YKS_PROC , pItem - > GetUnitID ( ) ) ;
}
else if ( YKS_ABRED = = action )
{
SetCOT ( & buffer [ 2 ] , IEC_101_104_COT_DEACTCON ) ;
}
else if ( YKS_EXEED = = action )
{
SetCOT ( & buffer [ 2 ] , IEC_101_104_COT_ACTTREM ) ;
m_gdwFile . PushYKLog ( system32 . now , ioa , value , YKT_EXERET , YKS_PROC , pItem - > GetUnitID ( ) ) ;
}
else
{
return 0 ;
}
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & buffer [ 2 + cot_length + asdu_addr_length ] , ioa ) ;
if ( ! SendIFrame ( buffer , ( 3 + cot_length + asdu_addr_length + info_addr_length ) , ord ) ) return - 1 ;
return 1 ;
}
int CSubGDW104Process : : MakeYTFrame ( CIEC104ProcessItem * pItem , int ord )
{
BYTE buffer [ 32 ] ;
if ( NULL = = pItem ) return - 1 ;
int order ;
BYTE action , result ;
DWORD value ;
if ( ! GetUnitYT ( pItem - > GetUnitID ( ) , order , value , action , result ) )
{
return 0 ;
}
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is %s result is %s \n " , pItem - > GetUnitID ( ) , order , value , val_to_str ( action , yt_state , " STATE=%d " ) , val_to_str ( result , yt_result , " RESULT=%d " ) ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
BYTE * param ;
BOOLEAN yt_type ;
DWORD ioa ;
int data_length = 2 ;
param = GetUnitYTParamByPoint ( pItem - > GetUnitID ( ) , order ) ;
ioa = MAKEDWORD ( MAKEWORD ( param [ 0 ] , param [ 1 ] ) , MAKEWORD ( param [ 2 ] , param [ 3 ] ) ) ;
yt_type = param [ 4 ] ;
if ( yt_type = = USE_YT_NA )
{ //双点遥控
data_length = 2 ;
buffer [ 0 ] = C_SE_NA_1 ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] = value & 0xff ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + 1 ] = ( value > > 8 ) & 0xff ;
}
else if ( yt_type = = USE_YT_NB )
{
data_length = 2 ;
buffer [ 0 ] = C_SE_NB_1 ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] = value & 0xff ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + 1 ] = ( value > > 8 ) & 0xff ;
}
else
{
data_length = 4 ;
buffer [ 0 ] = C_SE_NC_1 ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] = value & 0xff ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + 1 ] = ( value > > 8 ) & 0xff ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + 2 ] = ( value > > 16 ) & 0xff ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + 3 ] = ( value > > 24 ) & 0xff ;
}
buffer [ 1 ] = 1 ;
if ( YTS_SELED = = action & & YTR_FAIL = = result )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + data_length ] | = IEC_101_104_SE ;
action = YTS_ABRED ;
}
else if ( YTS_SELREQ = = action & & YTR_OVER = = result )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + data_length ] | = IEC_101_104_SE ;
action = YTS_ABRED ;
}
else if ( YTS_SELING = = action & & YTR_OVER = = result )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + data_length ] | = IEC_101_104_SE ;
action = YTS_ABRED ;
}
if ( YTS_SELED = = action )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + data_length ] | = IEC_101_104_SE ;
SetCOT ( & buffer [ 2 ] , IEC_101_104_COT_ACTCON ) ;
}
else if ( YTS_ABRED = = action )
{
SetCOT ( & buffer [ 2 ] , IEC_101_104_COT_DEACTCON ) ;
}
else if ( YTS_EXEED = = action )
{
SetCOT ( & buffer [ 2 ] , IEC_101_104_COT_ACTTREM ) ;
}
else
{
return FALSE ;
}
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & buffer [ 2 + cot_length + asdu_addr_length ] , ioa ) ;
if ( ! SendIFrame ( buffer , ( 3 + cot_length + asdu_addr_length + info_addr_length + data_length ) , ord ) ) return - 1 ;
return 1 ;
}
int CSubGDW104Process : : MakeFileFrame ( CIEC104ProcessItem * pItem , int ord )
{
//BYTE buffer[256];
if ( NULL = = pItem ) return - 1 ;
//文件上送判断
m_dwFileType = m_gdwFile . getCMD ( ) ;
if ( m_dwFileType )
{
if ( ( m_dwFileType & FIOCMD_VALID ) = = FIOCMD_READ_DIR )
{
return Send_CallFileDir_Confirm ( pItem , m_dwFileType , ord ) ;
}
else if ( ( m_dwFileType & FIOCMD_VALID ) = = FIOCMD_OPEN_FILE )
{
return Send_CallFileSel_Confirm ( pItem , m_dwFileType , ord ) ;
}
else if ( ( m_dwFileType & FIOCMD_VALID ) = = FIOCMD_READ_FILE )
{
return Send_CallFileDat_Ack ( pItem , m_dwFileType , ord ) ;
}
}
return 0 ;
}
int CSubGDW104Process : : Receive_Single_command ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE * pTarget , int & count ) //单点令
{
BYTE * pData = ( BYTE * ) pBuf ;
BYTE command ;
int uid , point ;
DWORD information_address ;
BOOLEAN value ;
BYTE SE ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
information_address = GetInformationAddr ( pData ) ; pData + = info_addr_length ;
command = * pData ;
pTarget [ 0 ] = C_SC_NA_1 ;
pTarget [ 1 ] = 1 ;
SetAsduAddr ( & pTarget [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & pTarget [ 2 + cot_length + asdu_addr_length ] , information_address ) ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length ] = command ;
count = 3 + cot_length + asdu_addr_length + info_addr_length ;
if ( IEC_101_104_COT_ACT = = cause_of_transmission | | IEC_101_104_COT_DEACT = = cause_of_transmission )
{
uid = pItem - > GetUnitID ( ) ;
BYTE ioa [ 4 ] ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYKPointByParam ( uid , ioa , 4 ) ;
if ( point < 0 )
{ //信息体地址错误
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_INFO ) ;
return ERROR_INFORMATION_ADDRESS ;
}
SE = GET_SE ( command ) ;
value = GET_SCO ( command ) ; pData + + ;
//判断该点是否为单点遥控及参数状态
BYTE * param ;
BOOLEAN yk_type ;
BYTE relay_type ;
param = GetUnitYKParamByPoint ( uid , point ) ;
yk_type = param [ 4 ] ;
relay_type = param [ 5 ] ;
if ( yk_type ! = USE_YK_SC )
{ //遥控类型错误,返回否定确认
SetCOT ( & pTarget [ 2 ] , ( ( cause_of_transmission + 1 ) | IEC_101_104_COT_PN ) ) ;
return ERROR_PARAM ;
}
if ( relay_type )
{
if ( relay_type = = 1 )
{ //Only on
if ( ! value )
{
vLog ( LOG_ERROR , " Only on,Cann't off! \n " ) ;
SetCOT ( & pTarget [ 2 ] , ( ( cause_of_transmission + 1 ) | IEC_101_104_COT_PN ) ) ;
return ERROR_PARAM ;
}
}
else
{ //Only off
if ( value )
{
vLog ( LOG_ERROR , " Only off,Cann't on! \n " ) ;
SetCOT ( & pTarget [ 2 ] , ( ( cause_of_transmission + 1 ) | IEC_101_104_COT_PN ) ) ;
return ERROR_PARAM ;
}
}
}
if ( IEC_101_104_COT_ACT = = cause_of_transmission )
{ //激活
if ( SE )
{ //选择
count = 0 ;
SetUnitYK ( uid , point , value , YKS_SELREQ , YKR_IDLE ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_SELREQ result is YKR_IDLE. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
m_gdwFile . PushYKLog ( system32 . now , information_address , value , YKT_SELREQ , YKS_PROC , uid ) ;
return NO_ERROR ;
}
else
{ //执行
SetUnitYK ( uid , point , value , YKS_EXEREQ , YKR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_EXEREQ result is YKR_IDLE. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
m_gdwFile . PushYKLog ( system32 . now , information_address , value , YKT_EXEREQ , YKS_PROC , uid ) ;
return NO_ERROR ;
}
}
else if ( IEC_101_104_COT_DEACT = = cause_of_transmission )
{ //激活终止
SetUnitYK ( uid , point , value , YKS_ABRREQ , YKR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_DEACTCON ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_ABRREQ result is YKR_IDLE. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
m_gdwFile . PushYKLog ( system32 . now , information_address , value , YKT_ABRREQ , YKS_PROC , uid ) ;
return NO_ERROR ;
}
}
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ;
}
int CSubGDW104Process : : Receive_Double_command ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE * pTarget , int & count ) //单点令
{
BYTE * pData = ( BYTE * ) pBuf ;
BYTE command ;
int uid , point ;
DWORD information_address ;
BOOLEAN value ;
BYTE SE ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
information_address = GetInformationAddr ( pData ) ; pData + = info_addr_length ;
command = * pData ;
pTarget [ 0 ] = C_DC_NA_1 ;
pTarget [ 1 ] = 1 ;
SetAsduAddr ( & pTarget [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & pTarget [ 2 + cot_length + asdu_addr_length ] , information_address ) ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length ] = command ;
count = 3 + cot_length + asdu_addr_length + info_addr_length ;
if ( IEC_101_104_COT_ACT = = cause_of_transmission | | IEC_101_104_COT_DEACT = = cause_of_transmission )
{
uid = pItem - > GetUnitID ( ) ;
BYTE ioa [ 4 ] ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYKPointByParam ( uid , ioa , 4 ) ;
if ( point < 0 )
{
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_INFO ) ;
count = 3 + cot_length + asdu_addr_length + info_addr_length ;
return ERROR_INFORMATION_ADDRESS ;
}
SE = GET_SE ( command ) ;
value = GET_DCO ( command ) ; pData + + ;
//判断该点是否为单点遥控及参数状态
BYTE * param ;
BOOLEAN yk_type ;
//BYTE relay_type;
param = GetUnitYKParamByPoint ( uid , point ) ;
yk_type = param [ 4 ] ;
//relay_type = param[5];
if ( yk_type = = USE_YK_SC )
{ //遥控类型错误,返回否定确认
SetCOT ( & pTarget [ 2 ] , ( ( cause_of_transmission + 1 ) | IEC_101_104_COT_PN ) ) ;
return ERROR_PARAM ;
}
if ( IEC_101_104_COT_ACT = = cause_of_transmission )
{ //激活
if ( SE )
{ //选择
count = 0 ;
SetUnitYK ( uid , point , value , YKS_SELREQ , YKR_IDLE ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_SELREQ result is YKR_IDLE. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
m_gdwFile . PushYKLog ( system32 . now , information_address , value , YKT_SELREQ , YKS_PROC , uid ) ;
return NO_ERROR ;
}
else
{ //执行
SetUnitYK ( uid , point , value , YKS_EXEREQ , YKR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_EXEREQ result is YKR_IDLE. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
m_gdwFile . PushYKLog ( system32 . now , information_address , value , YKT_EXEREQ , YKS_PROC , uid ) ;
return NO_ERROR ;
}
}
else if ( IEC_101_104_COT_DEACT = = cause_of_transmission )
{ //激活终止
SetUnitYK ( uid , point , value , YKS_ABRREQ , YKR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_DEACTCON ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_ABRREQ result is YKR_IDLE. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
m_gdwFile . PushYKLog ( system32 . now , information_address , value , YKT_ABRREQ , YKS_PROC , uid ) ;
return NO_ERROR ;
}
}
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ;
}
int CSubGDW104Process : : Receive_Set_point_command_normalized ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE * pTarget , int & count ) //设定规一化值命令
{
BYTE * pData = ( BYTE * ) pBuf ;
BYTE command ;
int uid , point ;
int information_address ;
WORD value = 0 ;
BYTE SE ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
information_address = GetInformationAddr ( pData ) ;
pData + = info_addr_length ;
value = ( WORD ) ( pData [ 0 ] | pData [ 1 ] < < 8 ) ;
pData + = 2 ;
command = * pData ;
pTarget [ 0 ] = C_SE_NA_1 ;
pTarget [ 1 ] = 1 ;
SetAsduAddr ( & pTarget [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & pTarget [ 2 + cot_length + asdu_addr_length ] , information_address ) ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length ] = value & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 1 ] = ( value > > 8 ) & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 2 ] = command ;
count = 3 + cot_length + asdu_addr_length + info_addr_length + 2 ;
if ( IEC_101_104_COT_ACT = = cause_of_transmission | | IEC_101_104_COT_DEACT = = cause_of_transmission )
{
uid = pItem - > GetUnitID ( ) ;
BYTE ioa [ 4 ] ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYTPointByParam ( uid , ioa , 4 ) ;
if ( point < 0 )
{
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_INFO ) ;
count = 3 + cot_length + asdu_addr_length + info_addr_length + 2 ;
return ERROR_INFORMATION_ADDRESS ;
}
SE = GET_SE ( command ) ;
//判断该点是否为单点遥控及参数状态
BYTE * param ;
BOOLEAN yt_type ;
param = GetUnitYTParamByPoint ( pItem - > GetUnitID ( ) , point ) ;
yt_type = param [ 4 ] ;
if ( yt_type ! = USE_YT_NA )
{ //遥控类型错误,返回否定确认
SetCOT ( & pTarget [ 2 ] , ( ( cause_of_transmission + 1 ) | IEC_101_104_COT_PN ) ) ;
return ERROR_PARAM ;
}
if ( IEC_101_104_COT_ACT = = cause_of_transmission )
{ //激活
if ( SE )
{ //选择
count = 0 ;
SetUnitYT ( uid , point , value , YTS_SELREQ , YTR_IDLE ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_SELREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
else
{ //执行
SetUnitYT ( uid , point , value , YTS_EXEREQ , YTR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_EXEREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
}
else if ( IEC_101_104_COT_DEACT = = cause_of_transmission )
{ //激活终止
SetUnitYT ( uid , point , value , YTS_ABRREQ , YTR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_DEACTCON ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_ABRREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
}
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ;
}
int CSubGDW104Process : : Receive_Set_point_command_scaled ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE * pTarget , int & count ) //设定标度化值命令
{
BYTE * pData = ( BYTE * ) pBuf ;
BYTE command ;
int uid , point ;
int information_address ;
WORD value = 0 ;
BYTE SE ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
information_address = GetInformationAddr ( pData ) ;
pData + = info_addr_length ;
value = ( WORD ) ( pData [ 0 ] | pData [ 1 ] < < 8 ) ;
pData + = 2 ;
command = * pData ;
pTarget [ 0 ] = C_SE_NB_1 ;
pTarget [ 1 ] = 1 ;
SetAsduAddr ( & pTarget [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & pTarget [ 2 + cot_length + asdu_addr_length ] , information_address ) ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length ] = value & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 1 ] = ( value > > 8 ) & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 2 ] = command ;
count = 3 + cot_length + asdu_addr_length + info_addr_length + 2 ;
if ( IEC_101_104_COT_ACT = = cause_of_transmission | | IEC_101_104_COT_DEACT = = cause_of_transmission )
{
uid = pItem - > GetUnitID ( ) ;
BYTE ioa [ 4 ] ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYTPointByParam ( uid , ioa , 4 ) ;
if ( point < 0 )
{
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_INFO ) ;
count = 3 + cot_length + asdu_addr_length + info_addr_length + 2 ;
return ERROR_INFORMATION_ADDRESS ;
}
SE = GET_SE ( command ) ;
//判断该点是否为单点遥控及参数状态
BYTE * param ;
BOOLEAN yt_type ;
param = GetUnitYTParamByPoint ( pItem - > GetUnitID ( ) , point ) ;
yt_type = param [ 4 ] ;
if ( yt_type ! = USE_YT_NB )
{ //遥控类型错误,返回否定确认
SetCOT ( & pTarget [ 2 ] , ( ( cause_of_transmission + 1 ) | IEC_101_104_COT_PN ) ) ;
return ERROR_PARAM ;
}
if ( IEC_101_104_COT_ACT = = cause_of_transmission )
{ //激活
if ( SE )
{ //选择
count = 0 ;
SetUnitYT ( uid , point , value , YTS_SELREQ , YTR_IDLE ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_SELREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
else
{ //执行
SetUnitYT ( uid , point , value , YTS_EXEREQ , YTR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_EXEREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
}
else if ( IEC_101_104_COT_DEACT = = cause_of_transmission )
{ //激活终止
SetUnitYT ( uid , point , value , YTS_ABRREQ , YTR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_DEACTCON ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_ABRREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
}
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ;
}
int CSubGDW104Process : : Receive_Set_point_command_short_floating ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE * pTarget , int & count ) //设定短浮点值命令
{
BYTE * pData = ( BYTE * ) pBuf ;
BYTE command ;
int uid , point ;
int information_address ;
DWORD value ;
BYTE SE ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
information_address = GetInformationAddr ( pData ) ;
pData + = info_addr_length ;
value = ( DWORD ) ( pData [ 0 ] | ( pData [ 1 ] < < 8 ) | ( pData [ 2 ] < < 16 ) | ( pData [ 3 ] < < 24 ) ) ;
pData + = 4 ;
command = * pData ;
pTarget [ 0 ] = C_SE_NC_1 ;
pTarget [ 1 ] = 1 ;
SetAsduAddr ( & pTarget [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & pTarget [ 2 + cot_length + asdu_addr_length ] , information_address ) ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length ] = value & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 1 ] = ( value > > 8 ) & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 2 ] = ( value > > 16 ) & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 3 ] = ( value > > 24 ) & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 4 ] = command ;
count = 3 + cot_length + asdu_addr_length + info_addr_length + 4 ;
if ( IEC_101_104_COT_ACT = = cause_of_transmission | | IEC_101_104_COT_DEACT = = cause_of_transmission )
{
uid = pItem - > GetUnitID ( ) ;
BYTE ioa [ 4 ] ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYTPointByParam ( uid , ioa , 4 ) ;
if ( point < 0 )
{
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_INFO ) ;
count = 3 + cot_length + asdu_addr_length + info_addr_length + 4 ;
return ERROR_INFORMATION_ADDRESS ;
}
SE = GET_SE ( command ) ;
//判断该点是否为单点遥控及参数状态
BYTE * param ;
BOOLEAN yt_type ;
param = GetUnitYTParamByPoint ( pItem - > GetUnitID ( ) , point ) ;
yt_type = param [ 4 ] ;
if ( yt_type ! = USE_YT_NC )
{ //遥控类型错误,返回否定确认
SetCOT ( & pTarget [ 2 ] , ( ( cause_of_transmission + 1 ) | IEC_101_104_COT_PN ) ) ;
return ERROR_PARAM ;
}
if ( IEC_101_104_COT_ACT = = cause_of_transmission )
{ //激活
if ( SE )
{ //选择
count = 0 ;
SetUnitYT ( uid , point , value , YTS_SELREQ , YTR_IDLE ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_SELREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
else
{ //执行
SetUnitYT ( uid , point , value , YTS_EXEREQ , YTR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_EXEREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
}
else if ( IEC_101_104_COT_DEACT = = cause_of_transmission )
{ //激活终止
SetUnitYT ( uid , point , value , YTS_ABRREQ , YTR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_DEACTCON ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_ABRREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
}
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ;
}
int CSubGDW104Process : : Receive_FileTrans ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission ) //读取文件
{
BYTE * pData = ( BYTE * ) pBuf ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
int information_address = GetInformationAddr ( pData ) ; pData + = info_addr_length ;
if ( information_address ! = 0 ) return ERROR_CAUSE_OF_TRANSMISSION ;
BYTE frameType = * pData ; pData + + ;
if ( frameType ! = FILE_TRS_TYPE ) return ERROR_UNKNOWN ;
BYTE command = * pData ; pData + + ;
if ( command = = ReadFileDirAct )
{
return parseFileReadDirAct ( pItem , pData ) ;
}
else if ( command = = ReadFileSelAct )
{
return parseFileReadFileSelAct ( pItem , pData ) ;
}
else if ( command = = ReadFileDataCon )
{
return parseFileReadFileDataCon ( pItem , pData ) ;
}
else if ( command = = WriteFileSelAct )
{
}
else if ( command = = WriteFileDataAct )
{
}
else
{
vLog ( LOG_ERROR , " 文件传输报文错误,不识别的操作标识 = %d. \n " , command ) ;
}
return ERROR_UNKNOWN ;
}
BOOLEAN CSubGDW104Process : : parseFileReadDirAct ( CIEC104ProcessItem * pItem , const BYTE * pData )
{
DWORD dirID = ( DWORD ) ( pData [ 0 ] | ( pData [ 1 ] < < 8 ) | ( pData [ 2 ] < < 16 ) | ( pData [ 3 ] < < 24 ) ) ; pData + = 4 ;
BYTE dirNameLength = * pData ; pData + + ;
char dirName [ FILE_PATH_LEN ] ;
memset ( dirName , ' \0 ' , sizeof ( dirName ) ) ;
if ( dirNameLength > 0 )
{
memcpy ( dirName , pData , dirNameLength ) ;
pData + = dirNameLength ;
}
BYTE callFlag = * pData ; pData + + ;
BOOLEAN callAllFiles = ( callFlag = = 0 ) ? TRUE : FALSE ;
unionCP56Time startTime ;
memcpy ( & startTime , & system32 . now , sizeof ( startTime ) ) ;
unionCP56Time endTime ;
memcpy ( & endTime , & system32 . now , sizeof ( endTime ) ) ;
if ( ! callAllFiles )
{
startTime . millisecond = * pData ; pData + + ;
startTime . millisecond | = ( * pData < < 8 ) ; pData + + ;
startTime . minute = * pData & 0x3f ;
startTime . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
startTime . hour = * pData & 0x1f ;
startTime . SU = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
startTime . dayofmonth = * pData & 0x1f ;
startTime . dayofweek = ( ( * pData & 0xe0 ) > > 5 ) ; pData + + ;
startTime . month = * pData & 0x0f ; pData + + ;
startTime . year = * pData & 0x7f ; pData + + ;
endTime . millisecond = * pData ; pData + + ;
endTime . millisecond | = ( * pData < < 8 ) ; pData + + ;
endTime . minute = * pData & 0x3f ;
endTime . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
endTime . hour = * pData & 0x1f ;
endTime . SU = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
endTime . dayofmonth = * pData & 0x1f ;
endTime . dayofweek = ( ( * pData & 0xe0 ) > > 5 ) ; pData + + ;
endTime . month = * pData & 0x0f ; pData + + ;
endTime . year = * pData & 0x7f ; pData + + ;
}
//判断文件目录
memset ( & m_FileDir , 0 , sizeof ( stCallFileDir ) ) ;
m_FileDir . allfile = callAllFiles ;
strcpy ( m_FileDir . dirname , dirName ) ;
m_FileDir . loadptr = 0 ;
m_FileDir . dirID = dirID ;
m_gdwFile . ReadDir ( dirName , callAllFiles , startTime , endTime ) ;
return TRUE ;
}
BOOLEAN CSubGDW104Process : : parseFileReadFileSelAct ( CIEC104ProcessItem * pItem , const BYTE * pData )
{
int fileNameLen = 0 ;
fileNameLen = * pData ; pData + + ;
if ( fileNameLen < = 0 )
{
vLog ( LOG_ERROR , " 文件名长度错误,文件名长度 = %d \n " , fileNameLen ) ;
return FALSE ;
}
char fileName [ FILE_PATH_LEN ] ;
memset ( fileName , ' \0 ' , sizeof ( fileName ) ) ;
memcpy ( fileName , pData , fileNameLen ) ; pData + = fileNameLen ;
strcpy ( m_FileDir . filename , fileName ) ;
m_FileDir . length = m_gdwFile . FileLength ( fileName ) ;
m_gdwFile . OpenFile ( fileName ) ;
return TRUE ;
}
BOOLEAN CSubGDW104Process : : parseFileReadFileDataCon ( CIEC104ProcessItem * pItem , const BYTE * pData )
{
LONG fileID = ( DWORD ) ( pData [ 0 ] | ( pData [ 1 ] < < 8 ) | ( pData [ 2 ] < < 16 ) | ( pData [ 3 ] < < 24 ) ) ; pData + = 4 ;
LONG filePos = ( DWORD ) ( pData [ 0 ] | ( pData [ 1 ] < < 8 ) | ( pData [ 2 ] < < 16 ) | ( pData [ 3 ] < < 24 ) ) ; pData + = 4 ;
vLog ( LOG_DEBUG , " 收到文件ID = %d 传输确认,数据段号 = %d, 原始文件应有长度 = %d \n " , fileID , filePos , m_FileDir . length ) ;
m_gdwFile . CloseFile ( ) ;
return FALSE ;
}
int CSubGDW104Process : : Send_FileDir ( CIEC104ProcessItem * pItem , BOOLEAN bErr , BOOLEAN follow , int count , int pos , int ord )
{
int len = 0 ;
BYTE buffer [ 1024 ] ;
if ( pItem = = NULL ) return - 1 ;
buffer [ len + + ] = GDW_F_FR_NA_1 ;
buffer [ len + + ] = 0 ; //VSQ此处无效
SetCOT ( & buffer [ len ] , IEC_101_104_COT_ACTCON ) ; len + = cot_length ;
SetAsduAddr ( & buffer [ len ] , pItem - > apdu_addr ) ; len + = asdu_addr_length ;
SetInformationAddr ( & buffer [ len ] , 0 ) ; len + = info_addr_length ;
buffer [ len + + ] = FILE_TRS_TYPE ; //文件传输
buffer [ len + + ] = ReadFileDirCon ; //读目录
if ( bErr )
{
buffer [ len + + ] = 1 ;
if ( ! SendIFrame ( buffer , len , ord ) ) return - 1 ;
return 1 ;
}
//结果描述字
buffer [ len + + ] = 0 ; //成功
//目录ID
buffer [ len + + ] = ( m_FileDir . dirID & 0xff ) ;
buffer [ len + + ] = ( ( m_FileDir . dirID > > 8 ) & 0xff ) ;
buffer [ len + + ] = ( ( m_FileDir . dirID > > 16 ) & 0xff ) ;
buffer [ len + + ] = ( ( m_FileDir . dirID > > 24 ) & 0xff ) ;
buffer [ len + + ] = follow ; //无后续
buffer [ len + + ] = count ; //文件数量
for ( int i = 0 ; i < count ; i + + )
{
std : : string filename = m_gdwFile . FileName ( i + pos ) ;
//名称长度
buffer [ len + + ] = filename . length ( ) ;
//文件名称
for ( int j = 0 ; j < ( int ) filename . length ( ) ; j + + )
{
buffer [ len + + ] = filename [ j ] ;
}
//文件属性
buffer [ len + + ] = 0 ;
//文件大小
len + = ValToBuf ( & buffer [ len ] , m_gdwFile . FileLength ( i + pos ) , 4 ) ;
//文件时间
unionCP56Time ct ;
ct = Time_ttounionCP56Time ( m_gdwFile . FileTime ( i + pos ) ) ;
len + = unionCP56TimeToBuf ( & buffer [ len ] , ct ) ;
}
if ( ! SendIFrame ( buffer , len , ord ) ) return - 1 ;
return 1 ;
}
int CSubGDW104Process : : Send_CallFileDir_Confirm ( CIEC104ProcessItem * pItem , DWORD cmd , int ord )
{
if ( cmd & CMD_EXEC_ERR )
{
return Send_FileDir ( pItem , TRUE , FALSE , 0 , 0 , ord ) ;
}
int count = m_gdwFile . FileCount ( ) ;
//默认文件名长度为32个字节
//一个文件信息长度为: 文件名称长度( 1) +文件名长度( 32) +文件属性( 1) +文件大小( 4) +文件时间( 7)
//默认一个文件信息占用48字节
//到此信息计算出一帧报文所能携带文件个数
int acount = ( max_frame - 17 - cot_length - asdu_addr_length - info_addr_length ) / 48 ; // = 4
int full_frame = count / acount ;
int si_frame = count % acount ;
int pos = 0 ;
for ( int i = 0 ; i < full_frame ; i + + )
{
Send_FileDir ( pItem , FALSE , TRUE , acount , pos , ord ) ;
pos + = acount ;
}
if ( si_frame ) Send_FileDir ( pItem , FALSE , FALSE , si_frame , pos , ord ) ;
return 1 ;
}
int CSubGDW104Process : : Send_CallFileSel_Confirm ( CIEC104ProcessItem * pItem , DWORD cmd , int ord )
{
int len = 0 ;
BYTE buffer [ 1024 ] ;
if ( pItem = = NULL ) return - 1 ;
buffer [ len + + ] = GDW_F_FR_NA_1 ;
buffer [ len + + ] = 0 ; //VSQ此处无效
SetCOT ( & buffer [ len ] , IEC_101_104_COT_ACTCON ) ; len + = cot_length ;
SetAsduAddr ( & buffer [ len ] , pItem - > apdu_addr ) ; len + = asdu_addr_length ;
SetInformationAddr ( & buffer [ len ] , 0 ) ; len + = info_addr_length ;
buffer [ len + + ] = FILE_TRS_TYPE ; //文件传输
buffer [ len + + ] = ReadFileSelCon ; //读文件激活确认
if ( cmd & CMD_EXEC_ERR )
{
//结果描述字
buffer [ len + + ] = 1 ; //失败
//没有文件
if ( ! SendIFrame ( buffer , len , ord ) ) return - 1 ;
return 1 ;
}
//结果描述字
buffer [ len + + ] = 0 ; //成功
std : : string filename = m_FileDir . filename ;
//名称长度
buffer [ len + + ] = filename . length ( ) ;
//文件名称
for ( int j = 0 ; j < ( int ) filename . length ( ) ; j + + )
{
buffer [ len + + ] = filename [ j ] ;
}
//文件ID
len + = ValToBuf ( & buffer [ len ] , 0 , 4 ) ;
//文件大小
len + = ValToBuf ( & buffer [ len ] , m_FileDir . length , 4 ) ;
if ( ! SendIFrame ( buffer , len , ord ) ) return - 1 ;
m_gdwFile . ReadFile ( ) ;
return 1 ;
}
int CSubGDW104Process : : Send_CallFileDat_Ack ( CIEC104ProcessItem * pItem , DWORD cmd , int ord )
{
int len = 0 ;
BYTE buffer [ 1024 ] ;
if ( pItem = = NULL ) return - 1 ;
buffer [ len + + ] = GDW_F_FR_NA_1 ;
buffer [ len + + ] = 0 ; //VSQ此处无效
SetCOT ( & buffer [ len ] , IEC_101_104_COT_ACTCON ) ; len + = cot_length ;
SetAsduAddr ( & buffer [ len ] , pItem - > apdu_addr ) ; len + = asdu_addr_length ;
SetInformationAddr ( & buffer [ len ] , 0 ) ; len + = info_addr_length ;
buffer [ len + + ] = FILE_TRS_TYPE ; //文件传输
buffer [ len + + ] = ReadFileDataAct ; //读文件激活确认
//文件ID
len + = ValToBuf ( & buffer [ len ] , 0 , 4 ) ;
//结果描述字
len + = m_gdwFile . FileData ( & buffer [ len ] ) ;
if ( ! SendIFrame ( buffer , len , ord ) ) return - 1 ;
return 1 ;
}