map/das-dn/hostmodbustcp/host_modbus_tcp.cpp
2024-10-14 20:26:21 +08:00

1514 lines
54 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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.//
///////////////////////////////////////////////////////////////////////////////////
#ifdef HAVE_FTP_PROCESS
#define MODBUSP_READ_ID 100 //读取文件及文件夹ID
#define MODBUSP_READ_ID_FUNCCODE 0x03 //读取文件及文件夹ID功能码。
#define MODBUSP_READ_ID_REGISTER_ADDRESS 0x01 //读取文件及文件夹ID寄存器地址。
#define MODBUSP_READ_ID_REGISTER_LENGTH 0x6 //读取文件及文件夹ID寄存器长须。
#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";
#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获取文件
snprintf(name, sizeof(name), "%d.rtd", mbt->m_currentFileNo + 1);
snprintf(remote, sizeof(remote), "ftp://%s/data/rtdatalog/%d/%d.rtd", str, mbt->m_currentDirNo + 1, mbt->m_currentFileNo + 1);
if (ftpget(remote, name, user, password)) {
//成功,处理文件
vLog(LOG_DEBUG, "get a file, then send to ws.\n");
mbt->m_lastDirNo = mbt->m_currentDirNo;
mbt->m_lastFileNo = mbt->m_currentFileNo;
mbt->m_currentFileNo++;
if (mbt->m_currentFileNo % 1000 == 0)
{ //一个文件夹最多存放1000个文件
mbt->m_currentFileNo = 0;
mbt->m_currentDirNo++;
if (mbt->m_currentDirNo >= 56)
{ //7天数据大约有56个文件夹
mbt->m_currentDirNo = 0;
}
}
}
}
pthread_exit(0);
return ((void*)0);
}
#endif
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();
}
CHostModbusTcpProcess::CHostModbusTcpProcess(noPollConn *conn)
{
m_nCount = 0;
m_nFrameCount = 0;
m_nCurFrame = 0;
m_nSendPoint = 0;
m_nCurBeginReg = 0;
m_nNeedSend = FALSE;
//websocket接口
if (conn != NULL)
{
m_conn = conn;
}
m_currentDirNo = -1; //当前目录编号
m_currentFileNo = -1; //当前文件编号
m_lastDirNo = -1; //上一目录编号
m_lastFileNo = -1; //上一文件编号
}
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;
}
//按寄存器排序
pItem->AddFrames(yxframes, ycframes, ymframes);
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];
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;
for (j = 0; j < MODBUS_RTU_AUTOMATIC_FRAME; j++)
{
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;
}
}
}
}
}
//按寄存器排序
pItem->AddFrames(yxframes, ycframes, ymframes);
}
}
}
BOOLEAN CHostModbusTcpProcess::OnPreCreate(int id)
{
if (!CNetProcess::OnPreCreate(id)) return FALSE;
m_nTimeout = 200;
calc2();
//启动后,读取本地文件更新最后一次的文件夹及文件序号
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;
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;
if ((m_currentDirNo == -1) && (m_currentFileNo == -1))
{ //当前文件和目录都为-1程序第一次启动。需要获取ftp目录及文件ID
/* code */
vLog(LOG_DEBUG, "here..... add read id frame.\n");
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;
}
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);
}
else if (m_nCurFrame == MODBUSP_READ_ID)
{
return OnReceiveIDData(pItem, &pData[3], count);
}
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;
}
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;
//根据结构来处理得到id信息
//
m_currentDirNo = 0;
m_currentFileNo = 0;
vLog(LOG_DEBUG, "create a ftp thread.\n");
//创建ftp线程
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[16];
snprintf(name, 16, "%s_ftp", GetCurProcessName());
pthread_setname_np(m_pid, name);
pthread_attr_destroy(&attr);
return TRUE;
}
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;
}