2024-07-08 10:27:17 +08:00
# include "host_modbus_tcp.h"
///////////////////////////////////////////////////////////////////////////////////
//Valid slave device addresses are in the range of 0 锟?C 247 decimal. //
//The individual slave devices are assigned addresses in the range of 1 锟?C 247. //
//Address 0 is used for the broadcast address, which all slave devices recognize.//
///////////////////////////////////////////////////////////////////////////////////
2024-10-15 14:10:59 +08:00
# define HAVE_FTP_PROCESS
2024-10-14 20:26:21 +08:00
# ifdef HAVE_FTP_PROCESS
2024-10-15 14:10:59 +08:00
# define MODBUSP_READ_ID 100 //读取文件及文件夹ID
2024-10-14 20:26:21 +08:00
# define MODBUSP_READ_ID_FUNCCODE 0x03 //读取文件及文件夹ID功能码。
2024-10-15 14:10:59 +08:00
# define MODBUSP_READ_ID_REGISTER_ADDRESS 150 //读取文件及文件夹ID寄存器地址。
# define MODBUSP_READ_ID_REGISTER_LENGTH 9 //读取文件及文件夹ID寄存器长度。
2024-10-14 20:26:21 +08:00
# include <curl/curl.h>
struct CustomProgress
{
curl_off_t lastruntime ;
CURL * curl ;
} ;
static int progressCallback ( void * p , curl_off_t dltotal , curl_off_t dlnow , curl_off_t ultotal , curl_off_t ulnow )
{
struct CustomProgress * progress = ( struct CustomProgress * ) p ;
CURL * curl = progress - > curl ;
curl_off_t curtime = 0 ;
curl_easy_getinfo ( curl , CURLINFO_TOTAL_TIME_T , & curtime ) ;
if ( ( curtime - progress - > lastruntime ) > = 3000000 ) {
progress - > lastruntime = curtime ;
fprintf ( stderr , " Total time: %f \n " , curtime ) ;
}
fprintf ( stderr , " UP: %ld bytes of %ld bytes, DOWN: %ld bytes of %ld bytes. \n " , ulnow , ultotal , dlnow , dltotal ) ;
if ( ultotal ) fprintf ( stderr , " UP progress: %0.2f \n " , float ( ulnow / ultotal ) ) ;
if ( dltotal ) fprintf ( stderr , " DOWN progress: %0.2f \n " , float ( dlnow / dltotal ) ) ;
return 0 ;
}
static size_t getContentLengthFunc ( void * ptr , size_t size , size_t nmemb , void * stream )
{
int r ;
long len = 0 ;
r = sscanf ( ( const char * ) ptr , " Content-Length: %ld \n " , & len ) ;
if ( r ) * ( ( long * ) stream ) = len ;
return size * nmemb ;
}
static size_t discardFunc ( void * ptr , size_t size , size_t nmemb , void * stream )
{
return size * nmemb ;
}
static size_t writefunc ( void * ptr , size_t size , size_t nmemb , FILE * stream )
{
return fwrite ( ptr , size , nmemb , stream ) ;
}
static int ftpget ( const char * remote , const char * local , const char * user , const char * pwd , const long timeout = 3 )
{
vLog ( LOG_DEBUG , " start to get %s to local %s, with name: %s, and password: %s. \n " , remote , local , user , pwd ) ;
curl_global_init ( CURL_GLOBAL_ALL ) ;
CURL * curl = curl_easy_init ( ) ;
char user_key [ 1024 ] = { 0 } ;
snprintf ( user_key , sizeof ( user_key ) , " %s:%s " , user , pwd ) ;
FILE * file ;
curl_off_t local_file_len = - 1 ;
long filesize = 0 ;
CURLcode ret = CURLE_GOT_NOTHING ;
struct stat file_info ;
int use_resume = 0 ;
if ( stat ( local , & file_info ) = = 0 ) {
local_file_len = file_info . st_size ;
use_resume = 1 ;
}
file = fopen ( local , " ab+ " ) ;
if ( file = = NULL ) {
vLog ( LOG_ERROR , " open file error(%d,%s) \n " , errno , strerror ( errno ) ) ;
return 0 ;
}
curl_easy_setopt ( curl , CURLOPT_URL , remote ) ;
curl_easy_setopt ( curl , CURLOPT_USERPWD , user_key ) ;
curl_easy_setopt ( curl , CURLOPT_CONNECTTIMEOUT , timeout ) ;
curl_easy_setopt ( curl , CURLOPT_HEADERFUNCTION , getContentLengthFunc ) ;
curl_easy_setopt ( curl , CURLOPT_HEADERDATA , & filesize ) ;
curl_easy_setopt ( curl , CURLOPT_RESUME_FROM_LARGE , use_resume ? local_file_len : 0 ) ;
curl_easy_setopt ( curl , CURLOPT_WRITEFUNCTION , writefunc ) ;
curl_easy_setopt ( curl , CURLOPT_WRITEDATA , file ) ;
ret = curl_easy_perform ( curl ) ;
fclose ( file ) ;
vLog ( LOG_DEBUG , " curl easy perform return value is: %d, and OK is: %d. \n " , ret , CURLE_OK ) ;
int curl_state = 0 ;
if ( ret = = CURLE_OK ) curl_state = 1 ;
else {
vLog ( LOG_ERROR , " %d,%s \n " , ret , curl_easy_strerror ( ret ) ) ;
curl_state = 0 ;
}
curl_easy_cleanup ( curl ) ;
curl_global_cleanup ( ) ;
return curl_state ;
}
static void * ryftp_process ( void * param )
{
if ( param = = NULL ) return ( ( void * ) 0 ) ;
CHostModbusTcpProcess * mbt = ( CHostModbusTcpProcess * ) param ;
//获取此协议配置里面的ftp信息
char remote_filename [ 64 ] ;
char remote_dirent [ 64 ] ;
char remote [ 256 ] ;
char name [ 128 ] ;
char local_filename [ 64 ] ;
char local_dirent [ 128 ] ;
//默认参数,或是通过协议配置获取
char user [ 128 ] = " administrator " ;
char password [ 128 ] = " 123456 " ;
char ipaddress [ 128 ] = " 127.0.0.1 " ;
2024-10-15 14:10:59 +08:00
//根据协议创建一个本地协议目录
int pid = mbt - > GetCurID ( ) ;
if ( pid < 0 | | pid > = PROCESSES_NUM ) return ( ( void * ) 0 ) ;
char pathName [ 128 ] ;
snprintf ( pathName , sizeof ( pathName ) , " %d " , pid ) ;
if ( mbt - > _mkdir ( pathName ) < 0 ) return ( ( void * ) 0 ) ;
//配置的用户名和密码
2024-10-14 20:26:21 +08:00
#if 0
snprintf ( user , sizeof ( user ) , " %s " , mbt - > m_user ) ;
snprintf ( password , sizeof ( password ) , " %s " , mbt - > m_password ) ;
# endif
char str [ 60 ] ;
DWORD target_addr = mbt - > target_addr ;
memset ( str , ' \0 ' , sizeof ( str ) ) ;
inet_ntop ( AF_INET , & target_addr , str , 16 ) ;
int i = 1 ;
while ( TRUE ) {
sleep ( 1 ) ; //每秒执行一次
//ftp获取文件
2024-10-15 14:10:59 +08:00
if ( mbt - > m_iv = = 1 ) {
//文件目录无效
continue ;
}
snprintf ( name , sizeof ( name ) , " %s/%d " , pathName , mbt - > m_currentFileNo ) ;
snprintf ( remote , sizeof ( remote ) , " ftp://%s/data/rtdatalog/%d/%d " , str , mbt - > m_currentDirNo , mbt - > m_currentFileNo ) ;
2024-10-14 20:26:21 +08:00
if ( ftpget ( remote , name , user , password ) ) {
//成功,处理文件
vLog ( LOG_DEBUG , " get a file, then send to ws. \n " ) ;
mbt - > m_lastFileNo = mbt - > m_currentFileNo ;
mbt - > m_currentFileNo + + ;
2024-10-15 14:10:59 +08:00
if ( ( mbt - > m_currentFileNo - mbt - > m_lastStartFileNo ) % 1000 = = 0 ) {
//一个文件夹最多存放1000个文件, mbt->m_currentFileNo = 0;
2024-10-14 20:26:21 +08:00
mbt - > m_currentDirNo + + ;
2024-10-15 14:10:59 +08:00
mbt - > m_lastStartFileNo = mbt - > m_currentFileNo ;
if ( mbt - > m_currentDirNo > = 56 ) { //7天数据大约有56个文件夹
2024-10-14 20:26:21 +08:00
mbt - > m_currentDirNo = 0 ;
}
2024-10-15 14:10:59 +08:00
//保存文件信息
2024-10-14 20:26:21 +08:00
}
}
}
pthread_exit ( 0 ) ;
return ( ( void * ) 0 ) ;
}
# endif
2024-07-08 10:27:17 +08:00
CHostModbusTcpProcessItem : : CHostModbusTcpProcessItem ( )
{
m_nNum = 0 ;
m_nFramePoll = 0 ;
apdu_t0_begin = 1 ;
m_nCurFrame = 0 ;
memset ( m_nModbusFrames , 0 , sizeof ( m_nModbusFrames ) ) ;
}
CHostModbusTcpProcessItem : : ~ CHostModbusTcpProcessItem ( )
{
m_nNum = 0 ;
m_nFramePoll = 0 ;
apdu_t0_begin = 1 ;
m_nCurFrame = 0 ;
memset ( m_nModbusFrames , 0 , sizeof ( m_nModbusFrames ) ) ;
}
void CHostModbusTcpProcessItem : : AddFrames ( struModbusExtFrame * yxs , struModbusExtFrame * ycs , struModbusExtFrame * yms )
{
int i = 0 , j = 0 ;
memset ( m_nModbusFrames , 0 , sizeof ( m_nModbusFrames ) ) ;
for ( j = 0 ; j < MODBUS_RTU_AUTOMATIC_FRAME ; j + + )
{
if ( yxs [ j ] . FrameType = = 0 | | yxs [ j ] . FuncCode = = 0 | | yxs [ j ] . RegCount = = 0 ) continue ;
memcpy ( & m_nModbusFrames [ i ] , & yxs [ j ] , sizeof ( struModbusExtFrame ) ) ;
i + + ;
if ( i > = MODBUS_RTU_AUTOMATIC_FRAME_MAX ) break ;
}
for ( j = 0 ; j < MODBUS_RTU_AUTOMATIC_FRAME ; j + + )
{
if ( ycs [ j ] . FrameType = = 0 | | ycs [ j ] . FuncCode = = 0 | | ycs [ j ] . RegCount = = 0 ) continue ;
memcpy ( & m_nModbusFrames [ i ] , & ycs [ j ] , sizeof ( struModbusExtFrame ) ) ;
i + + ;
if ( i > = MODBUS_RTU_AUTOMATIC_FRAME_MAX ) break ;
}
for ( j = 0 ; j < MODBUS_RTU_AUTOMATIC_FRAME ; j + + )
{
if ( yms [ j ] . FrameType = = 0 | | yms [ j ] . FuncCode = = 0 | | yms [ j ] . RegCount = = 0 ) continue ;
memcpy ( & m_nModbusFrames [ i ] , & yms [ j ] , sizeof ( struModbusExtFrame ) ) ;
i + + ;
if ( i > = MODBUS_RTU_AUTOMATIC_FRAME_MAX ) break ;
}
}
struModbusExtFrame * CHostModbusTcpProcessItem : : GetNextFrame ( void )
{
int last ;
if ( m_nCurFrame > = MODBUS_RTU_AUTOMATIC_FRAME_MAX ) return NULL ;
if ( m_nCurFrame < 0 ) m_nCurFrame = - 1 ;
last = m_nCurFrame ;
for ( m_nCurFrame + + ; m_nCurFrame < MODBUS_RTU_AUTOMATIC_FRAME_MAX ; m_nCurFrame + + )
{
if ( m_nModbusFrames [ m_nCurFrame ] . FuncCode = = 0 | | m_nModbusFrames [ m_nCurFrame ] . FrameType = = 0 ) break ;
return & m_nModbusFrames [ m_nCurFrame ] ;
}
for ( m_nCurFrame = 0 ; m_nCurFrame < = last ; m_nCurFrame + + )
{
if ( m_nModbusFrames [ m_nCurFrame ] . FuncCode = = 0 | | m_nModbusFrames [ m_nCurFrame ] . FrameType = = 0 ) break ;
return & m_nModbusFrames [ m_nCurFrame ] ;
}
return NULL ;
}
void CHostModbusTcpProcessItem : : Attach ( int uid , int sock , DWORD peer_addr , WORD peer_port )
{
CNetProcessItem : : Attach ( uid , sock , peer_addr , peer_port ) ;
apdu_t0_begin = 1 ;
m_nNum = 0 ;
m_nFramePoll = 0 ;
m_nCurFrame = 0 ;
}
void CHostModbusTcpProcessItem : : Release ( void )
{
apdu_t0_begin = 1 ;
m_nNum = 0 ;
m_nFramePoll = 0 ;
m_nCurFrame = 0 ;
CNetProcessItem : : Release ( ) ;
}
2024-10-14 20:26:21 +08:00
CHostModbusTcpProcess : : CHostModbusTcpProcess ( noPollConn * conn )
2024-07-08 10:27:17 +08:00
{
m_nCount = 0 ;
m_nFrameCount = 0 ;
m_nCurFrame = 0 ;
m_nSendPoint = 0 ;
m_nCurBeginReg = 0 ;
m_nNeedSend = FALSE ;
2024-10-14 20:26:21 +08:00
//websocket接口
2024-10-15 14:10:59 +08:00
m_conn = NULL ;
2024-10-14 20:26:21 +08:00
if ( conn ! = NULL )
{
m_conn = conn ;
}
2024-10-15 14:10:59 +08:00
m_pid = 0 ;
//目录无效
m_iv = 1 ;
2024-10-14 20:26:21 +08:00
m_currentDirNo = - 1 ; //当前目录编号
m_currentFileNo = - 1 ; //当前文件编号
m_lastDirNo = - 1 ; //上一目录编号
m_lastFileNo = - 1 ; //上一文件编号
2024-07-08 10:27:17 +08:00
}
CHostModbusTcpProcess : : ~ CHostModbusTcpProcess ( )
{
}
CNetProcessItem * CHostModbusTcpProcess : : CreateItem ( int ord )
{
return dynamic_cast < CNetProcessItem * > ( new CHostModbusTcpProcessItem ) ;
}
void CHostModbusTcpProcess : : DestroyItem ( int ord , BOOLEAN bDeleted /* = FALSE */ )
{
CHostModbusTcpProcessItem * pItem = ( CHostModbusTcpProcessItem * ) GetItem ( ord ) ;
if ( pItem ! = NULL & & ! bDeleted )
{
delete pItem ;
return CNetProcess : : DestroyItem ( ord , TRUE ) ;
}
return CNetProcess : : DestroyItem ( ord , bDeleted ) ;
}
void CHostModbusTcpProcess : : sort1 ( STRUCT_PARAM * params , int count )
{
int i , j , n ;
STRUCT_PARAM temp ;
n = count ;
for ( i = 0 ; i < n - 1 ; + + i ) //比较n-1轮
{
for ( j = 0 ; j < n - 1 - i ; + + j ) //每轮比较n-1-i次,
{
if ( params [ j ] . param [ 0 ] > params [ j + 1 ] . param [ 0 ] )
{
memcpy ( & temp , & params [ j ] , sizeof ( STRUCT_PARAM ) ) ;
memcpy ( & params [ j ] , & params [ j + 1 ] , sizeof ( STRUCT_PARAM ) ) ;
memcpy ( & params [ j + 1 ] , & temp , sizeof ( STRUCT_PARAM ) ) ;
}
}
}
}
void CHostModbusTcpProcess : : sort2 ( STRUCT_PARAM * params , int count )
{
int i , j , n ;
STRUCT_PARAM temp ;
n = count ;
for ( i = 0 ; i < n - 1 ; + + i ) //比较n-1轮
{
for ( j = 0 ; j < n - 1 - i ; + + j ) //每轮比较n-1-i次,
{
int addr1 = ( int ) MAKEWORD ( params [ j ] . param [ 1 ] , params [ j ] . param [ 2 ] ) ;
int addr2 = ( int ) MAKEWORD ( params [ j + 1 ] . param [ 1 ] , params [ j + 1 ] . param [ 2 ] ) ;
if ( addr1 > addr2 )
{
memcpy ( & temp , & params [ j ] , sizeof ( STRUCT_PARAM ) ) ;
memcpy ( & params [ j ] , & params [ j + 1 ] , sizeof ( STRUCT_PARAM ) ) ;
memcpy ( & params [ j + 1 ] , & temp , sizeof ( STRUCT_PARAM ) ) ;
}
}
}
}
void CHostModbusTcpProcess : : calc2 ( void )
{
int i , j , n , uid ;
BYTE addr ;
CHostModbusTcpProcessItem * pItem ;
for ( i = 0 ; i < PROCESS_UNIT_NUM ; i + + )
{
pItem = ( CHostModbusTcpProcessItem * ) GetItem ( i ) ;
if ( NULL = = pItem ) continue ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) continue ;
if ( GetUnitAddr ( uid , & addr , 1 ) )
{ //获取单元地址成功,则该段原地址采用配置地址,否则该单元为无效地址。
pItem - > m_addr = addr ;
}
struModbusExtFrame ycframes [ MODBUS_RTU_AUTOMATIC_FRAME ] ;
struModbusExtFrame ymframes [ MODBUS_RTU_AUTOMATIC_FRAME ] ;
struModbusExtFrame yxframes [ MODBUS_RTU_AUTOMATIC_FRAME ] ;
memset ( ycframes , 0 , sizeof ( ycframes ) ) ;
memset ( ymframes , 0 , sizeof ( ymframes ) ) ;
memset ( yxframes , 0 , sizeof ( yxframes ) ) ;
struUnitModbusOption option ;
if ( GetUnitOption ( uid , & option , sizeof ( option ) ) )
{
if ( option . use_owner_config )
{ //采用协议配置
if ( option . modbus . yx1Enable )
{
yxframes [ 0 ] . FrameType = MODBUSP_READ_YX1 ;
yxframes [ 0 ] . FuncCode = option . modbus . yx1FuncCode ;
yxframes [ 0 ] . RegBegin = option . modbus . yx1Begin ;
yxframes [ 0 ] . RegCount = option . modbus . yx1Count ;
}
if ( option . modbus . yx2Enable )
{
yxframes [ 1 ] . FrameType = MODBUSP_READ_YX1 ;
yxframes [ 1 ] . FuncCode = option . modbus . yx2FuncCode ;
yxframes [ 1 ] . RegBegin = option . modbus . yx2Begin ;
yxframes [ 1 ] . RegCount = option . modbus . yx2Count ;
}
if ( option . modbus . yc1Enable )
{
ycframes [ 0 ] . FrameType = MODBUSP_READ_YC1 ;
ycframes [ 0 ] . FuncCode = option . modbus . yc1FuncCode ;
ycframes [ 0 ] . RegBegin = option . modbus . yc1Begin ;
ycframes [ 0 ] . RegCount = option . modbus . yc1Count ;
}
if ( option . modbus . yc2Enable )
{
ycframes [ 1 ] . FrameType = MODBUSP_READ_YC1 ;
ycframes [ 1 ] . FuncCode = option . modbus . yc2FuncCode ;
ycframes [ 1 ] . RegBegin = option . modbus . yc2Begin ;
ycframes [ 1 ] . RegCount = option . modbus . yc2Count ;
}
if ( option . modbus . yc3Enable )
{
ycframes [ 2 ] . FrameType = MODBUSP_READ_YC1 ;
ycframes [ 2 ] . FuncCode = option . modbus . yc3FuncCode ;
ycframes [ 2 ] . RegBegin = option . modbus . yc3Begin ;
ycframes [ 2 ] . RegCount = option . modbus . yc3Count ;
}
if ( option . modbus . yc4Enable )
{
ycframes [ 3 ] . FrameType = MODBUSP_READ_YC1 ;
ycframes [ 3 ] . FuncCode = option . modbus . yc4FuncCode ;
ycframes [ 3 ] . RegBegin = option . modbus . yc4Begin ;
ycframes [ 3 ] . RegCount = option . modbus . yc4Count ;
}
if ( option . modbus . ym1Enable )
{
ymframes [ 0 ] . FrameType = MODBUSP_READ_YM1 ;
ymframes [ 0 ] . FuncCode = option . modbus . ym1FuncCode ;
ymframes [ 0 ] . RegBegin = option . modbus . ym1Begin ;
ymframes [ 0 ] . RegCount = option . modbus . ym1Count ;
}
if ( option . modbus . ym2Enable )
{
ymframes [ 1 ] . FrameType = MODBUSP_READ_YM1 ;
ymframes [ 1 ] . FuncCode = option . modbus . ym2FuncCode ;
ymframes [ 1 ] . RegBegin = option . modbus . ym2Begin ;
ymframes [ 1 ] . RegCount = option . modbus . ym2Count ;
}
//按寄存器排序
2024-09-24 15:59:22 +08:00
pItem - > AddFrames ( yxframes , ycframes , ymframes ) ;
2024-07-08 10:27:17 +08:00
continue ;
}
}
{
int yccount , ymcount , yxcount ;
yccount = GetUnitYCCount ( uid ) ;
ymcount = GetUnitYMCount ( uid ) ;
yxcount = GetUnitYXCount ( uid ) ;
STRUCT_PARAM * ycparam = NULL , * ymparam = NULL , * yxparam = NULL ;
if ( yccount ) ycparam = new STRUCT_PARAM [ yccount ] ;
if ( ymcount ) ymparam = new STRUCT_PARAM [ ymcount ] ;
if ( yxcount ) yxparam = new STRUCT_PARAM [ yxcount ] ;
2024-10-15 14:10:59 +08:00
#if 0
//插入一帧读取信息的报文
ycframes [ 0 ] . FrameType = MODBUSP_READ_ID ;
ycframes [ 0 ] . FuncCode = MODBUSP_READ_ID_FUNCCODE ;
ycframes [ 0 ] . RegBegin = MODBUSP_READ_ID_REGISTER_ADDRESS ;
ycframes [ 0 ] . RegCount = MODBUSP_READ_ID_REGISTER_LENGTH ;
j = 1 ;
# else
j = 0 ;
# endif
2024-07-08 10:27:17 +08:00
if ( ycparam )
{
memset ( ycparam , 0 , sizeof ( STRUCT_PARAM ) * yccount ) ;
for ( n = 0 ; n < yccount ; n + + )
{
memcpy ( ycparam [ n ] . param , GetUnitYCParamByPoint ( uid , n ) , sizeof ( STRUCT_PARAM ) ) ;
}
//按功能码排序
sort1 ( ycparam , yccount ) ;
//按寄存器地址排序
sort2 ( ycparam , yccount ) ;
//组帧
for ( n = 0 ; n < yccount ; n + + )
{
WORD addr = MAKEWORD ( ycparam [ n ] . param [ 1 ] , ycparam [ n ] . param [ 2 ] ) ;
if ( addr > = 65535 ) continue ;
2024-10-15 14:10:59 +08:00
for ( ; j < MODBUS_RTU_AUTOMATIC_FRAME ; j + + )
2024-07-08 10:27:17 +08:00
{
if ( ycframes [ j ] . FuncCode = = 0 )
{
ycframes [ j ] . FrameType = MODBUSP_READ_YC1 ;
ycframes [ j ] . FuncCode = ycparam [ n ] . param [ 0 ] ;
ycframes [ j ] . RegBegin = addr ;
ycframes [ j ] . RegCount = ycparam [ n ] . param [ 3 ] ;
break ;
}
if ( ycframes [ j ] . FuncCode = = ycparam [ n ] . param [ 0 ] )
{
if ( addr < = MODBUS_MAX_WORD_REGISTER_NUM + ycframes [ j ] . RegBegin )
{
int len = addr - ycframes [ j ] . RegBegin ;
if ( len )
{
ycframes [ j ] . RegCount = len + ycparam [ n ] . param [ 3 ] ;
}
else
{
vLog ( LOG_DEBUG , " 遥测测点配置了相同的功能码和寄存器地址 \n " ) ;
}
break ;
}
}
}
}
}
if ( ymparam )
{
memset ( ymparam , 0 , sizeof ( STRUCT_PARAM ) * ymcount ) ;
for ( n = 0 ; n < ymcount ; n + + )
{
memcpy ( ymparam [ n ] . param , GetUnitYMParamByPoint ( uid , n ) , sizeof ( STRUCT_PARAM ) ) ;
}
sort1 ( ymparam , ymcount ) ;
sort2 ( ymparam , ymcount ) ;
//组帧
for ( n = 0 ; n < ymcount ; n + + )
{
WORD addr = MAKEWORD ( ymparam [ n ] . param [ 1 ] , ymparam [ n ] . param [ 2 ] ) ;
if ( addr > = 65535 ) continue ;
for ( j = 0 ; j < MODBUS_RTU_AUTOMATIC_FRAME ; j + + )
{
if ( ymframes [ j ] . FuncCode = = 0 )
{
ymframes [ j ] . FrameType = MODBUSP_READ_YM1 ;
ymframes [ j ] . FuncCode = ymparam [ n ] . param [ 0 ] ;
ymframes [ j ] . RegBegin = addr ;
ymframes [ j ] . RegCount = ymparam [ n ] . param [ 3 ] ;
break ;
}
if ( ymframes [ j ] . FuncCode = = ymparam [ n ] . param [ 0 ] )
{
if ( addr < = MODBUS_MAX_WORD_REGISTER_NUM + ymframes [ j ] . RegBegin )
{
int len = addr - ymframes [ j ] . RegBegin ;
if ( len )
{
ymframes [ j ] . RegCount = len + ymparam [ n ] . param [ 3 ] ;
}
else
{
vLog ( LOG_DEBUG , " 遥脉测点配置了相同的功能码和寄存器地址 \n " ) ;
}
break ;
}
}
}
}
}
if ( yxparam )
{
memset ( yxparam , 0 , sizeof ( STRUCT_PARAM ) * yxcount ) ;
for ( n = 0 ; n < yxcount ; n + + )
{
memcpy ( yxparam [ n ] . param , GetUnitYXParamByPoint ( uid , n ) , sizeof ( STRUCT_PARAM ) ) ;
}
sort1 ( yxparam , yxcount ) ;
sort2 ( yxparam , yxcount ) ;
//组帧
for ( n = 0 ; n < yxcount ; n + + )
{
WORD addr = MAKEWORD ( yxparam [ n ] . param [ 1 ] , yxparam [ n ] . param [ 2 ] ) ;
if ( addr > = 65535 ) continue ;
for ( j = 0 ; j < MODBUS_RTU_AUTOMATIC_FRAME ; j + + )
{
if ( yxframes [ j ] . FuncCode = = 0 )
{
yxframes [ j ] . FrameType = MODBUSP_READ_YX1 ;
yxframes [ j ] . FuncCode = yxparam [ n ] . param [ 0 ] ;
yxframes [ j ] . RegBegin = addr ;
yxframes [ j ] . RegCount = 1 ;
break ;
}
if ( yxframes [ j ] . FuncCode = = yxparam [ n ] . param [ 0 ] )
{
int len = addr - yxframes [ j ] . RegBegin ;
if ( len )
{
if ( yxframes [ j ] . FuncCode = = MODBUSC_F01 | | yxframes [ j ] . FuncCode = = MODBUSC_F02 )
{
if ( addr < = MODBUS_MAX_BITMAP_REGISTER_NUM + yxframes [ j ] . RegBegin )
{
yxframes [ j ] . RegCount = len + 1 ;
break ;
}
}
else if ( yxframes [ j ] . FuncCode = = MODBUSC_F03 | | yxframes [ j ] . FuncCode = = MODBUSC_F04 )
{
if ( addr < = MODBUS_MAX_WORD_REGISTER_NUM + yxframes [ j ] . RegBegin )
{
yxframes [ j ] . RegCount = len + 1 ;
break ;
}
}
}
else
{
if ( yxframes [ j ] . FuncCode = = MODBUSC_F01 | | yxframes [ j ] . FuncCode = = MODBUSC_F02 )
{
vLog ( LOG_DEBUG , " 遥信测点配置了相同的功能码和寄存器地址 \n " ) ;
}
break ;
}
}
}
}
}
//按寄存器排序
2024-09-24 15:59:22 +08:00
pItem - > AddFrames ( yxframes , ycframes , ymframes ) ;
2024-07-08 10:27:17 +08:00
}
}
}
BOOLEAN CHostModbusTcpProcess : : OnPreCreate ( int id )
{
if ( ! CNetProcess : : OnPreCreate ( id ) ) return FALSE ;
m_nTimeout = 200 ;
calc2 ( ) ;
2024-10-15 14:10:59 +08:00
//启动后, 创建ftp线程
if ( m_pid < = 0 ) {
vLog ( LOG_DEBUG , " create a ftp thread. \n " ) ;
pthread_attr_t attr ;
pthread_attr_init ( & attr ) ;
pthread_attr_setstacksize ( & attr , MEMERY_1M ) ;
pthread_attr_setscope ( & attr , PTHREAD_SCOPE_SYSTEM ) ;
if ( pthread_create ( & m_pid , & attr , ryftp_process , this ) < 0 ) {
vLog ( LOG_ERROR , " create ryftp_process error(%d,%s). \n " , errno , strerror ( errno ) ) ;
return TRUE ;
}
char name [ 17 ] ;
snprintf ( name , 16 , " %s_ftp " , GetCurProcessName ( ) ) ;
pthread_setname_np ( m_pid , name ) ;
pthread_attr_destroy ( & attr ) ;
}
2024-07-08 10:27:17 +08:00
return TRUE ;
}
BOOLEAN CHostModbusTcpProcess : : Run ( void )
{
int count ;
BYTE buffer [ 512 ] ;
if ( ! CNetProcess : : Run ( ) ) return FALSE ;
FeedDog ( ) ;
//process polling command
CHostModbusTcpProcessItem * pItem = ( CHostModbusTcpProcessItem * ) GetItem ( 0 ) ;
if ( NULL = = pItem ) return TRUE ;
if ( pItem - > GetSock ( ) < 0 ) {
usleep ( 20000 ) ;
return TRUE ;
}
pItem = ( CHostModbusTcpProcessItem * ) GetCurItem ( ) ;
if ( NULL = = pItem ) return TRUE ;
buffer [ 0 ] = HIBYTE ( pItem - > m_nNum ) ; buffer [ 1 ] = LOBYTE ( pItem - > m_nNum ) ;
buffer [ 2 ] = 0 ; buffer [ 3 ] = MB_TCP_PROTOCOL_ID ;
if ( ( m_nCurFrame = = 0 & & m_nNeedSend ) )
{
count = 0 ;
if ( GetYKFrame ( pItem , & buffer [ 6 ] , count , m_nCurFrame , m_nCurFuncCode ) )
{ //insert yk command
}
else if ( GetYTFrame ( pItem , & buffer [ 6 ] , count , m_nCurFrame , m_nCurFuncCode ) )
{ //insert yt command
}
else if ( pItem - > m_nFramePoll & MODBUSP_SET_TIME_FRAME )
{
pItem - > m_nFramePoll & = ~ MODBUSP_SET_TIME_FRAME ;
if ( GetSetTimeFrame ( pItem , & buffer [ 6 ] , count ) )
{
m_nCurFrame = 0 ;
}
}
else if ( pItem - > m_nFramePoll & MODBUSP_GET_DATA_FRAME )
{
pItem - > m_nFramePoll & = ~ MODBUSP_GET_DATA_FRAME ;
if ( GetReadDataFrame ( pItem , & buffer [ 6 ] , count ) )
{
m_nCurFrame = m_nFrameType ;
}
}
if ( count > = 2 )
{ //发送前清除接收缓冲区所有数据
buffer [ 4 ] = HIBYTE ( count ) ;
buffer [ 5 ] = LOBYTE ( count ) ;
if ( WriteData ( buffer , count + 6 , 0 ) )
{
DisplayTxData ( buffer , count + 6 , TRUE ) ;
}
pItem - > m_nNum + + ;
m_nSendPoint = system32 . ticks ; //0;
m_nNeedSend = FALSE ;
2024-10-15 14:10:59 +08:00
//fprintf(stderr, "tx<%d>: ", count+6); for (int a = 0; a < count+6; a++) fprintf(stderr, "%02X ", buffer[a]); fprintf(stderr, "\n");
2024-07-08 10:27:17 +08:00
FeedDog ( ) ;
}
}
return TRUE ;
}
BOOLEAN CHostModbusTcpProcess : : OnTimer ( void )
{
CHostModbusTcpProcessItem * pItem ;
if ( ! CNetProcess : : OnTimer ( ) ) return FALSE ;
m_nCount + + ;
pItem = ( CHostModbusTcpProcessItem * ) GetItem ( 0 ) ;
if ( NULL = = pItem ) return FALSE ;
if ( pItem - > GetSock ( ) < 0 )
{
if ( ( pItem - > apdu_t0_begin + 30 ) < system32 . timers )
{
pItem - > apdu_t0_begin = system32 . timers ;
Connect ( pItem , 0 , TRUE ) ;
}
return TRUE ;
}
if ( m_nCurFrame ! = 0 )
{
if ( m_nSendPoint & & ( m_nSendPoint + m_nTimeout ) < = system32 . ticks )
{ //0.5 second command time out
m_nSendPoint = 0 ;
m_nCurFrame = 0 ;
}
}
if ( m_nCurFrame = = 0 & & ( m_nCount % PollGap ( ) ) = = 0 )
{
pItem = ( CHostModbusTcpProcessItem * ) GetNextItem ( ) ;
if ( pItem = = NULL ) return TRUE ;
m_nNeedSend = TRUE ;
2024-10-15 14:10:59 +08:00
# if 1
//启动时读取一次,后面自己维护序号
2024-10-14 20:26:21 +08:00
if ( ( m_currentDirNo = = - 1 ) & & ( m_currentFileNo = = - 1 ) )
{ //当前文件和目录都为-1, 程序第一次启动。需要获取ftp目录及文件ID
m_nFrameType = MODBUSP_READ_ID ;
m_nCurFuncCode = MODBUSP_READ_ID_FUNCCODE ;
m_nCurBeginReg = MODBUSP_READ_ID_REGISTER_ADDRESS ;
m_nCurRegCount = MODBUSP_READ_ID_REGISTER_LENGTH ;
pItem - > m_nFramePoll | = MODBUSP_GET_DATA_FRAME ;
return TRUE ;
}
2024-10-15 14:10:59 +08:00
# endif
2024-07-08 10:27:17 +08:00
struModbusExtFrame * frame = pItem - > GetNextFrame ( ) ;
if ( frame ! = NULL )
{
m_nFrameType = frame - > FrameType ;
m_nCurFuncCode = frame - > FuncCode ;
m_nCurBeginReg = frame - > RegBegin ;
m_nCurRegCount = frame - > RegCount ;
pItem - > m_nFramePoll | = MODBUSP_GET_DATA_FRAME ;
return TRUE ;
}
}
return TRUE ;
}
BOOLEAN CHostModbusTcpProcess : : GetYKFrame ( CHostModbusTcpProcessItem * pItem , BYTE * pBuf , int & count , DWORD & frame , BYTE & FuncCode )
{
int uid ;
BYTE result ;
BYTE * pData ;
if ( NULL = = pItem ) return FALSE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
if ( NULL = = pBuf ) return FALSE ;
pData = pBuf ;
if ( ! GetUnitYK ( uid , m_nYKOrder , m_bYKValue , m_nYKState , result ) )
{
return FALSE ;
}
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is %s result is %s. \n " , uid , m_nYKOrder , ( m_bYKValue ? " ClOSE " : " TRIP " ) , val_to_str ( m_nYKState , yk_state , " STATE = %d " ) , val_to_str ( result , yk_result , " RESULT = %d " ) ) ;
BYTE * m_param ;
BYTE nFun ; //功能码
BOOLEAN nNeedSelect ; //遥控需要选择
WORD nReg , nVal ;
WORD nCloseSelReg , nCloseExecReg , nCloseEscReg , nCloseValue ; //合闸命令参数
WORD nOpenSelReg , nOpenExecReg , nOpenEscReg , nOpenValue ; //分闸命令参数
m_param = GetUnitYKParamByPoint ( uid , m_nYKOrder ) ;
if ( NULL = = m_param ) return FALSE ;
nFun = m_param [ 0 ] ; //功能码占一个字节
nNeedSelect = m_param [ 1 ] ; //遥控是否需要选择
nCloseSelReg = MAKEWORD ( m_param [ 4 ] , m_param [ 5 ] ) ; //选择合寄存器
nCloseExecReg = MAKEWORD ( m_param [ 6 ] , m_param [ 7 ] ) ; //执行合寄存器
nCloseEscReg = MAKEWORD ( m_param [ 8 ] , m_param [ 9 ] ) ; //撤销合寄存器
nCloseValue = MAKEWORD ( m_param [ 10 ] , m_param [ 11 ] ) ; //合
nOpenSelReg = MAKEWORD ( m_param [ 12 ] , m_param [ 13 ] ) ; //选择分寄存器
nOpenExecReg = MAKEWORD ( m_param [ 14 ] , m_param [ 15 ] ) ; //执行分寄存器
nOpenEscReg = MAKEWORD ( m_param [ 16 ] , m_param [ 17 ] ) ; //撤销分寄存器
nOpenValue = MAKEWORD ( m_param [ 18 ] , m_param [ 19 ] ) ; //分
if ( m_nYKState = = YKS_SELREQ )
{ //遥控选择
if ( m_bYKValue )
{
nReg = nCloseSelReg ;
nVal = nCloseValue ;
}
else
{
nReg = nOpenSelReg ;
nVal = nOpenValue ;
}
if ( 0xffff = = nReg | | ! nNeedSelect )
{ //寄存器无效,遥控无须选择
SetUnitYK ( uid , m_nYKOrder , m_bYKValue , YKS_SELED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_SELED result is YKR_SUCC. \n " , uid , m_nYKOrder , ( m_bYKValue ? " CLOSE " : " TRIP " ) ) ;
return FALSE ;
}
else
{
pData [ 0 ] = pItem - > m_addr ;
pData [ 1 ] = nFun ;
pData [ 2 ] = ( nReg > > 8 ) & 0x00ff ;
pData [ 3 ] = nReg & 0x00ff ;
pData [ 4 ] = ( nVal > > 8 ) & 0x00ff ;
pData [ 5 ] = nVal & 0x00ff ;
count = 6 ;
FuncCode = nFun ;
frame = MODBUSP_YK_SELECT ;
return TRUE ;
}
}
else if ( m_nYKState = = YKS_EXEREQ )
{ //遥控执行
if ( m_bYKValue )
{
nReg = nCloseExecReg ;
nVal = nCloseValue ;
}
else
{
nReg = nOpenExecReg ;
nVal = nOpenValue ;
}
if ( 0xffff = = nReg ) return FALSE ;
pData [ 0 ] = pItem - > m_addr ;
pData [ 1 ] = nFun ;
pData [ 2 ] = ( nReg > > 8 ) & 0x00ff ;
pData [ 3 ] = nReg & 0x00ff ;
pData [ 4 ] = ( nVal > > 8 ) & 0x00ff ;
pData [ 5 ] = nVal & 0x00ff ;
count = 6 ;
FuncCode = nFun ;
frame = MODBUSP_YK_EXECUTE ;
return TRUE ;
}
else if ( m_nYKState = = YKS_ABRREQ )
{ //遥控撤销
if ( m_bYKValue )
{
nReg = nCloseEscReg ;
nVal = nCloseValue ;
}
else
{
nReg = nOpenEscReg ;
nVal = nOpenValue ;
}
if ( 0xffff = = nReg | | ! nNeedSelect )
{ //寄存器无效
SetUnitYK ( uid , m_nYKOrder , m_bYKValue , YKS_ABRED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC. \n " , uid , m_nYKOrder , ( m_bYKValue ? " CLOSE " : " TRIP " ) ) ;
return FALSE ;
}
pData [ 0 ] = pItem - > m_addr ;
pData [ 1 ] = nFun ;
pData [ 2 ] = ( nReg > > 8 ) & 0x00ff ;
pData [ 3 ] = nReg & 0x00ff ;
pData [ 4 ] = ( nVal > > 8 ) & 0x00ff ;
pData [ 5 ] = nVal & 0x00ff ;
count = 6 ;
FuncCode = nFun ;
frame = MODBUSP_YK_CANCEL ;
return TRUE ;
}
else if ( ( m_nYKState = = YKS_SELING | | m_nYKState = = YKS_SELED ) & & result = = YKR_OVER )
{ //遥控撤销
if ( m_bYKValue )
{
nReg = nCloseEscReg ;
nVal = nCloseValue ;
}
else
{
nReg = nOpenEscReg ;
nVal = nOpenValue ;
}
if ( 0xffff = = nReg | | ! nNeedSelect )
{ //寄存器无效
SetUnitYK ( uid , m_nYKOrder , m_bYKValue , YKS_ABRED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC. \n " , uid , m_nYKOrder , ( m_bYKValue ? " CLOSE " : " TRIP " ) ) ;
return FALSE ;
}
pData [ 0 ] = pItem - > m_addr ;
pData [ 1 ] = nFun ;
pData [ 2 ] = ( nReg > > 8 ) & 0x00ff ;
pData [ 3 ] = nReg & 0x00ff ;
pData [ 4 ] = ( nVal > > 8 ) & 0x00ff ;
pData [ 5 ] = nVal & 0x00ff ;
count = 6 ;
FuncCode = nFun ;
frame = MODBUSP_YK_CANCEL ;
return TRUE ;
}
return FALSE ;
}
//////////////////////////////////////////////////////////////////////////
// yt start //
//////////////////////////////////////////////////////////////////////////
BOOLEAN CHostModbusTcpProcess : : GetYTFrame ( CHostModbusTcpProcessItem * pItem , BYTE * pBuf , int & count , DWORD & frame , BYTE & FuncCode )
{
int uid ;
BYTE result ;
BYTE * pData ;
if ( NULL = = pItem ) return FALSE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
if ( NULL = = pBuf ) return FALSE ;
pData = pBuf ;
if ( ! GetUnitYT ( uid , m_nYTOrder , m_dwYTValue , m_nYTState , result ) )
{
return FALSE ;
}
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is %s result is %s. \n " , uid , m_nYTOrder , m_dwYTValue , val_to_str ( m_nYTState , yt_state , " STATE = %d " ) , val_to_str ( result , yt_result , " RESULT = %d " ) ) ;
BYTE * m_param ;
BYTE nFun ; //功能码
BYTE nSetType ; //设置方式 0单寄存器, 1双寄存器
BOOLEAN nNeedSelect ; //遥设需要选择
WORD nReg = 0xffff ;
WORD nSelReg , nExecReg , nEscReg ; //合闸命令参数
m_param = GetUnitYTParamByPoint ( uid , m_nYTOrder ) ;
if ( NULL = = m_param ) return FALSE ;
nSetType = m_param [ 0 ] ; //0 16位整型值;1 32位整型值;2 32位浮点数值;
nFun = m_param [ 1 ] ; //功能码占一个字节
nNeedSelect = m_param [ 2 ] ; //遥控是否需要选择
nSelReg = MAKEWORD ( m_param [ 4 ] , m_param [ 5 ] ) ; //选择寄存器
nExecReg = MAKEWORD ( m_param [ 6 ] , m_param [ 7 ] ) ; //执行寄存器
nEscReg = MAKEWORD ( m_param [ 8 ] , m_param [ 9 ] ) ; //撤销寄存器
if ( m_nYTState = = YTS_SELREQ )
{ //遥设选择
nReg = nSelReg ;
if ( 0xffff = = nReg | | ! nNeedSelect )
{ //寄存器无效,遥设无须选择
SetUnitYT ( uid , m_nYTOrder , m_dwYTValue , YTS_SELED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_SELED result is YTR_SUCC. \n " , uid , m_nYTOrder , m_dwYTValue ) ;
return FALSE ;
}
else
{
FuncCode = nFun ;
frame = MODBUSP_YT_SELECT ;
}
}
else if ( m_nYTState = = YTS_EXEREQ )
{ //遥设执行
nReg = nExecReg ;
if ( 0xffff = = nReg ) return FALSE ;
FuncCode = nFun ;
frame = MODBUSP_YT_EXECUTE ;
}
else if ( m_nYTState = = YTS_ABRREQ )
{ //遥设撤销
nReg = nEscReg ;
if ( 0xffff = = nReg | | ! nNeedSelect )
{ //寄存器无效
SetUnitYT ( uid , m_nYTOrder , m_dwYTValue , YTS_ABRED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC. \n " , uid , m_nYTOrder , m_dwYTValue ) ;
return FALSE ;
}
FuncCode = nFun ;
frame = MODBUSP_YT_CANCEL ;
}
else if ( ( m_nYTState = = YTS_SELING | | m_nYTState = = YTS_SELED ) & & result = = YTR_OVER )
{ //遥设撤销
nReg = nEscReg ;
if ( 0xffff = = nReg | | ! nNeedSelect )
{ //寄存器无效
SetUnitYT ( uid , m_nYTOrder , m_dwYTValue , YTS_ABRED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC. \n " , uid , m_nYTOrder , m_dwYTValue ) ;
return FALSE ;
}
FuncCode = nFun ;
frame = MODBUSP_YT_CANCEL ;
}
//modify by assouan for clean;
pData [ 0 ] = pItem - > m_addr ;
pData [ 1 ] = nFun ;
pData [ 2 ] = ( nReg > > 8 ) & 0x00ff ;
pData [ 3 ] = nReg & 0x00ff ;
if ( nFun = = MODBUSC_F06 )
{
pData [ 4 ] = ( m_dwYTValue > > 8 ) & 0x00ff ;
pData [ 5 ] = m_dwYTValue & 0x00ff ;
count = 6 ;
}
else if ( nFun = = MODBUSC_F16 )
{
if ( nSetType = = 0 )
{
pData [ 4 ] = 0x00 ;
pData [ 5 ] = 0x01 ;
pData [ 6 ] = 0x02 ;
pData [ 7 ] = ( m_dwYTValue > > 8 ) & 0x00ff ;
pData [ 8 ] = m_dwYTValue & 0x00ff ;
count = 9 ;
}
else if ( nSetType = = 1 )
{
pData [ 4 ] = 0x00 ;
pData [ 5 ] = 0x02 ;
pData [ 6 ] = 0x04 ;
pData [ 7 ] = ( m_dwYTValue > > 24 ) & 0x00ff ;
pData [ 8 ] = ( m_dwYTValue > > 16 ) & 0x00ff ;
pData [ 9 ] = ( m_dwYTValue > > 8 ) & 0x00ff ;
pData [ 10 ] = m_dwYTValue & 0x00ff ;
count = 11 ;
}
else if ( nSetType = = 2 )
{
pData [ 4 ] = 0x00 ;
pData [ 5 ] = 0x02 ;
pData [ 6 ] = 0x04 ;
pData [ 7 ] = ( m_dwYTValue > > 8 ) & 0x00ff ;
pData [ 8 ] = m_dwYTValue & 0x00ff ;
pData [ 9 ] = ( m_dwYTValue > > 24 ) & 0x00ff ;
pData [ 10 ] = ( m_dwYTValue > > 16 ) & 0x00ff ;
count = 11 ;
}
}
else return FALSE ;
return TRUE ;
}
//////////////////////////////////////////////////////////////////////////
// yt end //
//////////////////////////////////////////////////////////////////////////
BOOLEAN CHostModbusTcpProcess : : GetSetTimeFrame ( CHostModbusTcpProcessItem * pItem , BYTE * /*pData*/ , int & /*count*/ )
{
return TRUE ;
}
BOOLEAN CHostModbusTcpProcess : : GetReadDataFrame ( CHostModbusTcpProcessItem * pItem , BYTE * pData , int & count )
{
if ( NULL = = pItem ) return FALSE ;
if ( m_nFrameType = = 0 ) return FALSE ;
if ( m_nCurFuncCode = = 0 ) return FALSE ;
pData [ 0 ] = pItem - > m_addr ;
pData [ 1 ] = ( BYTE ) m_nCurFuncCode ;
pData [ 2 ] = ( m_nCurBeginReg > > 8 ) & 0x00ff ;
pData [ 3 ] = m_nCurBeginReg & 0x00ff ;
pData [ 4 ] = ( m_nCurRegCount > > 8 ) & 0x00ff ;
pData [ 5 ] = m_nCurRegCount & 0x00ff ;
count = 6 ;
return TRUE ;
}
int CHostModbusTcpProcess : : OnPackageReceived ( BYTE * pBuf , int count , int ord )
{
int uid ;
if ( count < 6 )
{ //数据长度不足
return 0 ;
}
CHostModbusTcpProcessItem * pItem ;
pItem = ( CHostModbusTcpProcessItem * ) GetItem ( ord ) ;
if ( NULL = = pItem ) return - 1 ;
//头尾判断。
WORD protocol , len ;
protocol = MAKEWORD ( pBuf [ 3 ] , pBuf [ 2 ] ) ;
len = MAKEWORD ( pBuf [ 5 ] , pBuf [ 4 ] ) ;
if ( count < len + 6 )
{ //数据接收未完
return 0 ;
}
if ( protocol ! = MB_TCP_PROTOCOL_ID )
{ //未知协议
return - 1 ;
}
BYTE * buffer = & pBuf [ 6 ] ;
if ( ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F01 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F02 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F03 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F04 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F05 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F06 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F07 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F08 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F11 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F12 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F15 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F16 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F17 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F20 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F21 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F22 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F23 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F24 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F43 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F26 ) )
{ //不支持的功能码
return - 1 ;
}
if ( ( buffer [ 1 ] & 0x80 ) = = 0x80 )
{ //错误代码
m_nCurFrame = 0 ;
}
//根据地址查找单元id
uid = GetUnitByAddr ( buffer , 1 ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return ( len + 6 ) ;
int order = GetOrderByUnitID ( uid ) ;
if ( order < 0 | | order > = PROCESS_UNIT_NUM ) return ( len + 6 ) ;
pItem = ( CHostModbusTcpProcessItem * ) GetItem ( order ) ;
if ( NULL = = pItem ) return ( len + 6 ) ;
if ( OnReceiveData ( pItem , buffer , ( len - 3 ) ) )
{
m_nCurFrame = 0 ;
}
DisplayRxData ( pBuf , ( len + 6 ) , TRUE , uid ) ;
UnitFeedDog ( uid ) ;
return ( len + 6 ) ;
}
BOOLEAN CHostModbusTcpProcess : : OnReceiveData ( CHostModbusTcpProcessItem * pItem , BYTE * pData , int count )
{
int uid ;
if ( NULL = = pItem ) return FALSE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 ) return FALSE ;
UnitFeedDog ( uid ) ;
if ( pData [ 1 ] = = m_nCurFuncCode )
{
if ( m_nCurFrame = = MODBUSP_READ_YX1 )
{
return OnReceiveYXData ( pItem , & pData [ 3 ] , count ) ;
}
else if ( m_nCurFrame = = MODBUSP_READ_YC1 )
{
return OnReceiveYCData ( pItem , & pData [ 3 ] , count ) ;
}
else if ( m_nCurFrame = = MODBUSP_READ_YM1 )
{
return OnReceiveYMData ( pItem , & pData [ 3 ] , count ) ;
}
2024-10-14 20:26:21 +08:00
else if ( m_nCurFrame = = MODBUSP_READ_ID )
{
return OnReceiveIDData ( pItem , & pData [ 3 ] , count ) ;
}
2024-07-08 10:27:17 +08:00
else if ( m_nCurFrame = = MODBUSP_YK_EXECUTE )
{
SetUnitYK ( uid , m_nYKOrder , m_bYKValue , YKS_EXEED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_EXEED result is YKR_SUCC. \n " , uid , m_nYKOrder , ( m_bYKValue ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
else if ( MODBUSP_YK_SELECT = = m_nCurFrame )
{
SetUnitYK ( uid , m_nYKOrder , m_bYKValue , YKS_SELED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_SELED result is YKR_SUCC. \n " , uid , m_nYKOrder , ( m_bYKValue ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
else if ( MODBUSP_YK_CANCEL = = m_nCurFrame )
{
SetUnitYK ( uid , m_nYKOrder , m_bYKValue , YKS_ABRED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC. \n " , uid , m_nYKOrder , ( m_bYKValue ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
else if ( MODBUSP_YT_EXECUTE = = m_nCurFrame )
{
SetUnitYT ( uid , m_nYTOrder , m_dwYTValue , YTS_EXEED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_EXEED result is YTR_SUCC. \n " , uid , m_nYTOrder , m_dwYTValue ) ;
return TRUE ;
}
else if ( MODBUSP_YT_SELECT = = m_nCurFrame )
{
SetUnitYT ( uid , m_nYTOrder , m_dwYTValue , YTS_SELED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_SELED result is YTR_SUCC. \n " , uid , m_nYTOrder , m_dwYTValue ) ;
return TRUE ;
}
else if ( MODBUSP_YT_CANCEL = = m_nCurFrame )
{
SetUnitYT ( uid , m_nYTOrder , m_dwYTValue , YTS_ABRED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC. \n " , uid , m_nYTOrder , m_dwYTValue ) ;
return TRUE ;
}
}
return FALSE ;
}
2024-10-14 20:26:21 +08:00
BOOLEAN CHostModbusTcpProcess : : OnReceiveIDData ( CHostModbusTcpProcessItem * pItem , BYTE * pData , int count )
{
int i ;
int point ;
int uid ;
BYTE * pBuf ;
if ( pItem = = NULL ) return FALSE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 ) return FALSE ;
pBuf = pData ;
2024-10-15 14:10:59 +08:00
/*
1 ) 、 路 径 信 息 是 否 有 效 byte ;
2 ) 、 当 前 文 件 夹 路 径 名 的 后 缀 dint , 按 照 顺 序 增 加 1 ( 转 字 符 串 时 在 前 补 0 ) ;
3 ) 、 当 前 文 件 夹 下 最 后 新 文 件 的 编 号 dint ;
4 ) 、 当 前 文 件 夹 下 第 一 个 文 件 的 编 号 dint ;
5 ) 、 当 前 文 件 夹 下 文 件 个 数 dint ;
*/
//路径有效性判断
int iv = ( ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ; pBuf + = 2 ;
m_iv = iv ;
if ( iv ) {
vLog ( LOG_DEBUG , " 路径信息无效 \n " ) ;
return FALSE ;
}
//当前文件夹路径名
m_currentDirNo = ( DWORD ) ( ( pBuf [ 2 ] < < 24 ) | ( pBuf [ 3 ] < < 16 ) | ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ; pBuf + = 4 ;
//当前文件夹下最后新文件
m_currentFileNo = ( DWORD ) ( ( pBuf [ 2 ] < < 24 ) | ( pBuf [ 3 ] < < 16 ) | ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ; pBuf + = 4 ;
//当前文件夹下第一个文件
m_lastStartFileNo = ( DWORD ) ( ( pBuf [ 2 ] < < 24 ) | ( pBuf [ 3 ] < < 16 ) | ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ; pBuf + = 4 ;
2024-10-14 20:26:21 +08:00
2024-10-15 14:10:59 +08:00
vLog ( LOG_DEBUG , " dir: %d, file: %d: start: %d \n " , m_currentDirNo , m_currentFileNo , m_lastStartFileNo ) ;
2024-10-14 20:26:21 +08:00
return TRUE ;
}
2024-07-08 10:27:17 +08:00
BOOLEAN CHostModbusTcpProcess : : OnReceiveYXData ( CHostModbusTcpProcessItem * pItem , BYTE * pData , int count )
{
int uid ;
int i , j ;
int point ;
BYTE param [ 4 ] ;
WORD reg ;
BOOLEAN yxVal ;
if ( pItem = = NULL ) return FALSE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 ) return FALSE ;
reg = m_nCurBeginReg ;
param [ 0 ] = m_nCurFuncCode ;
if ( MODBUSC_F03 = = m_nCurFuncCode | | MODBUSC_F04 = = m_nCurFuncCode )
{ //03功能码读取Holdings
WORD nValue ;
WORD nTemp = 0x0001 ;
for ( i = 0 ; i < count ; i + = 2 )
{
nValue = ( pData [ i ] < < 8 ) | pData [ i + 1 ] ;
nTemp = 0x0001 ;
param [ 1 ] = LOBYTE ( reg ) ;
param [ 2 ] = HIBYTE ( reg ) ;
reg + + ;
for ( j = 0 ; j < 16 ; j + + )
{
param [ 3 ] = j ;
point = GetUnitYXPointByParam ( uid , param , 4 ) ;
if ( point > = 0 )
{
yxVal = SPI_OFF ;
if ( ( nValue ) & nTemp )
{
yxVal = SPI_ON ;
}
SetUnitYX ( uid , point , yxVal ) ;
}
nTemp < < = 1 ;
}
}
}
else if ( MODBUSC_F01 = = m_nCurFuncCode | | MODBUSC_F02 = = m_nCurFuncCode )
{ //01 02功能码读取Coils和Status
BYTE * nValue = pData ;
BYTE nTemp = 0x01 ;
for ( i = 0 ; i < count ; i + + )
{
nTemp = 0x01 ;
for ( j = 0 ; j < 8 ; j + + )
{
param [ 1 ] = LOBYTE ( reg ) ;
param [ 2 ] = HIBYTE ( reg ) ;
reg + + ;
point = GetUnitYXPointByParam ( uid , param , 3 ) ;
if ( point > = 0 )
{
yxVal = SPI_OFF ;
if ( ( * nValue ) & nTemp )
{
yxVal = SPI_ON ;
}
SetUnitYX ( uid , point , yxVal ) ;
}
nTemp < < = 1 ;
}
nValue + + ;
}
}
return TRUE ;
}
BOOLEAN CHostModbusTcpProcess : : OnReceiveYCData ( CHostModbusTcpProcessItem * pItem , BYTE * pData , int count )
{
int uid ;
int i ;
BYTE * pBuf ;
BYTE * pParam ;
BYTE param [ 8 ] ;
DWORD nValue = 0 ;
LONG bin_value ;
float f_val ;
int point ;
WORD reg ;
BYTE reg_count , value_type , sign_mark ;
if ( pItem = = NULL ) return FALSE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 ) return FALSE ;
pBuf = pData ;
reg = m_nCurBeginReg ;
param [ 0 ] = m_nCurFuncCode ;
for ( i = 0 ; i < count ; )
{
param [ 1 ] = LOBYTE ( reg ) ;
param [ 2 ] = HIBYTE ( reg ) ;
point = GetUnitYCPointByParam ( uid , param , 3 ) ;
if ( point > = 0 )
{ //获得合法点号
pParam = GetUnitYCParamByPoint ( uid , point ) ;
if ( pParam ! = NULL )
{
reg_count = pParam [ 3 ] ;
value_type = pParam [ 4 ] ;
sign_mark = pParam [ 5 ] ;
if ( ( 1 = = reg_count ) & & ( 2 = = value_type ) )
{ //16位归一化值
if ( 2 = = value_type )
{
if ( sign_mark = = 0 ) nValue = ( DWORD ) ( WORD ) ( ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
else nValue = ( DWORD ) ( short ) ( ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
SetUnitYC ( uid , point , ( LONG ) nValue ) ;
}
else if ( 8 = = value_type )
{
if ( sign_mark = = 0 ) nValue = ( DWORD ) ( WORD ) ( ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
else nValue = ( DWORD ) ( short ) ( ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
nValue = bcd_to_int ( ( const BYTE * ) & nValue , sizeof ( WORD ) ) ;
SetUnitYC ( uid , point , ( LONG ) nValue ) ;
}
pBuf + = 2 ; i + = 2 ; reg + + ;
}
else if ( 2 = = reg_count )
{ //32位测量值
if ( 0 = = value_type )
{ //浮点数,高位在第一个寄存器
nValue = ( DWORD ) ( pBuf [ 0 ] < < 24 | pBuf [ 1 ] < < 16 | pBuf [ 2 ] < < 8 | pBuf [ 3 ] ) ;
memcpy ( & f_val , & nValue , 4 ) ;
SetUnitYC ( uid , point , f_val ) ;
//nValue = (DWORD)(f_val * 1000);
}
else if ( 1 = = value_type )
{
nValue = ( DWORD ) ( pBuf [ 2 ] < < 24 | pBuf [ 3 ] < < 16 | pBuf [ 0 ] < < 8 | pBuf [ 1 ] ) ;
memcpy ( & f_val , & nValue , 4 ) ;
SetUnitYC ( uid , point , f_val ) ;
//nValue = (DWORD)(f_val * 1000);
}
else if ( 3 = = value_type )
{ //归一化值,高位在第一个寄存器
nValue = ( DWORD ) ( pBuf [ 0 ] < < 24 | pBuf [ 1 ] < < 16 | pBuf [ 2 ] < < 8 | pBuf [ 3 ] ) ;
SetUnitYC ( uid , point , ( LONG ) nValue ) ;
}
else if ( 4 = = value_type )
{ //归一化值,高位在第二个寄存器
nValue = ( DWORD ) ( pBuf [ 2 ] < < 24 | pBuf [ 3 ] < < 16 | pBuf [ 0 ] < < 8 | pBuf [ 1 ] ) ;
SetUnitYC ( uid , point , ( LONG ) nValue ) ;
}
else if ( 5 = = value_type )
{
nValue = ( DWORD ) ( pBuf [ 3 ] < < 24 | pBuf [ 2 ] < < 16 | pBuf [ 1 ] < < 8 | pBuf [ 0 ] ) ;
memcpy ( & f_val , & nValue , 4 ) ;
SetUnitYC ( uid , point , f_val ) ;
}
else if ( 6 = = value_type )
{ //32位bcd数据高位在第一个寄存器
nValue = ( DWORD ) ( ( pBuf [ 0 ] < < 24 ) | ( pBuf [ 1 ] < < 16 ) | ( pBuf [ 2 ] < < 8 ) | pBuf [ 3 ] ) ;
bin_value = ( LONG ) bcd_to_int ( ( const BYTE * ) & nValue , sizeof ( DWORD ) ) ;
SetUnitYC ( uid , point , bin_value ) ;
}
else if ( 7 = = value_type )
{ //32位bcd数据高位在第二个寄存器
nValue = ( DWORD ) ( pBuf [ 2 ] < < 24 | pBuf [ 3 ] < < 16 | pBuf [ 0 ] < < 8 | pBuf [ 1 ] ) ;
bin_value = ( LONG ) bcd_to_int ( ( const BYTE * ) & nValue , sizeof ( DWORD ) ) ;
SetUnitYC ( uid , point , bin_value ) ;
}
pBuf + = 4 ; i + = 4 ; reg + = 2 ;
}
}
}
else
{
pBuf + = 2 ; i + = 2 ; reg + + ;
}
}
return TRUE ;
}
BOOLEAN CHostModbusTcpProcess : : OnReceiveYMData ( CHostModbusTcpProcessItem * pItem , BYTE * pData , int count )
{
int i ;
int point ;
int uid ;
BYTE * pBuf ;
BYTE * pParam ;
BYTE nParam [ 4 ] ;
BYTE value_type ;
WORD reg ;
DWORD nValue = 0 ;
float f_val ;
DWORD dw [ 2 ] ; //双精度转换中间变量
double d_val ;
DWORD bin_value ;
if ( pItem = = NULL ) return FALSE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 ) return FALSE ;
pBuf = pData ;
reg = m_nCurBeginReg ;
nParam [ 0 ] = m_nCurFuncCode ;
for ( i = 0 ; i < count ; )
{
nParam [ 1 ] = LOBYTE ( reg ) ;
nParam [ 2 ] = HIBYTE ( reg ) ;
point = GetUnitYMPointByParam ( uid , nParam , 3 ) ;
if ( point > = 0 )
{ //获得有效点号
pParam = GetUnitYMParamByPoint ( uid , point ) ;
if ( NULL ! = pParam )
{ //获得有效参数
value_type = pParam [ 4 ] ;
if ( 0 = = value_type )
{ //16位无符号整型
nValue = ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ;
SetUnitYM ( uid , point , nValue ) ;
pBuf + = 2 ; i + = 2 ; reg + + ;
}
else if ( 1 = = value_type )
{ //32位无符号整型高位在第一个寄存器
nValue = ( DWORD ) ( ( pBuf [ 0 ] < < 24 ) | ( pBuf [ 1 ] < < 16 ) | ( pBuf [ 2 ] < < 8 ) | pBuf [ 3 ] ) ;
SetUnitYM ( uid , point , nValue ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else if ( 2 = = value_type )
{ //32位整型高位在第一个寄存器
nValue = ( DWORD ) ( ( pBuf [ 0 ] < < 24 ) | ( pBuf [ 1 ] < < 16 ) | ( pBuf [ 2 ] < < 8 ) | pBuf [ 3 ] ) ;
SetUnitYM ( uid , point , nValue ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else if ( 3 = = value_type )
{ //32位无符号整型高位在第二个寄存器
nValue = ( DWORD ) ( ( pBuf [ 2 ] < < 24 ) | ( pBuf [ 3 ] < < 16 ) | ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
SetUnitYM ( uid , point , nValue ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else if ( 4 = = value_type )
{ //32位整型高位在第二个寄存器
nValue = ( DWORD ) ( ( pBuf [ 2 ] < < 24 ) | ( pBuf [ 3 ] < < 16 ) | ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
SetUnitYM ( uid , point , nValue ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else if ( 5 = = value_type )
{ //32位浮点数高位在第一个寄存器
nValue = ( DWORD ) ( ( pBuf [ 0 ] < < 24 ) | ( pBuf [ 1 ] < < 16 ) | ( pBuf [ 2 ] < < 8 ) | pBuf [ 3 ] ) ;
memcpy ( & f_val , & nValue , 4 ) ;
SetUnitYM ( uid , point , ( DWORD ) f_val ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else if ( 6 = = value_type )
{ //32位浮点数高位在第二个寄存器
nValue = ( DWORD ) ( ( pBuf [ 2 ] < < 24 ) | ( pBuf [ 3 ] < < 16 ) | ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
memcpy ( & f_val , & nValue , 4 ) ;
SetUnitYM ( uid , point , ( DWORD ) f_val ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else if ( 7 = = value_type )
{ //64位浮点数高位在第一个寄存器
dw [ 1 ] = ( DWORD ) ( ( pBuf [ 2 ] < < 24 ) | ( pBuf [ 3 ] < < 16 ) | ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
dw [ 0 ] = ( DWORD ) ( ( pBuf [ 6 ] < < 24 ) | ( pBuf [ 7 ] < < 16 ) | ( pBuf [ 4 ] < < 8 ) | pBuf [ 5 ] ) ;
memcpy ( & d_val , dw , 8 ) ;
SetUnitYM ( uid , point , ( DWORD ) ( d_val ) ) ;
pBuf + = 8 ; reg + = 4 ; i + = 8 ;
}
else if ( 8 = = value_type )
{
dw [ 0 ] = ( DWORD ) ( ( pBuf [ 2 ] < < 24 ) | ( pBuf [ 3 ] < < 16 ) | ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
dw [ 1 ] = ( DWORD ) ( ( pBuf [ 6 ] < < 24 ) | ( pBuf [ 7 ] < < 16 ) | ( pBuf [ 4 ] < < 8 ) | pBuf [ 5 ] ) ;
memcpy ( & d_val , dw , 8 ) ;
SetUnitYM ( uid , point , ( DWORD ) ( d_val ) ) ;
pBuf + = 8 ; reg + = 4 ; i + = 8 ;
}
else if ( 9 = = value_type )
{
nValue = ( DWORD ) ( ( pBuf [ 3 ] < < 24 ) | ( pBuf [ 2 ] < < 16 ) | ( pBuf [ 1 ] < < 8 ) | pBuf [ 0 ] ) ;
memcpy ( & f_val , & nValue , 4 ) ;
SetUnitYM ( uid , point , ( DWORD ) ( f_val * 10 ) ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else if ( 10 = = value_type )
{ //32位bcd数据
nValue = ( DWORD ) ( ( pBuf [ 0 ] < < 24 ) | ( pBuf [ 1 ] < < 16 ) | ( pBuf [ 2 ] < < 8 ) | pBuf [ 3 ] ) ;
bin_value = bcd_to_int ( ( const BYTE * ) & nValue , sizeof ( DWORD ) ) ;
SetUnitYM ( uid , point , bin_value ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else
{ //无配置
pBuf + = 2 ; reg + + ; i + = 2 ;
}
}
}
else
{
pBuf + = 2 ; i + = 2 ; reg + + ;
}
}
return TRUE ;
}