map/das-dn/hostadsbf/hostadsbf.cpp
2024-12-11 16:30:53 +08:00

1316 lines
50 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 "hostadsbf.h"
#include <array>
#include <math.h>
#include <ry.h>
#define MAX_BLOCKF_SIZE 512
#define DATA_BLOCK_BOUNDARY 400
#define REGISTER_DATA_TYPE_YC 1
#define REGISTER_DATA_TYPE_YM 2
#define REGISTER_DATA_TYPE_YX_BYTE 3
#define REGISTER_DATA_TYPE_YX_WORD 4
#define REGISTER_DATA_TYPE_YX_DWORD 5
#define ADSP_READ_ID 100 //读取文件及文件夹ID
#define ADSP_READ_ID_FUNCCODE 0x03 //读取文件及文件夹ID功能码。
#define ADSP_READ_ID_REGISTER_ADDRESS 300 //读取文件及文件夹ID寄存器地址。
#define ADSP_READ_ID_REGISTER_LENGTH 32 //读取文件及文件夹ID寄存器长度。
static datalen2mbaddrmap m_datalen2mbaddr_map;
static struDataLengthMBAddr m_datalen_mbaddr[] = {
{ 1, 400 },
{ 1, 402 },
{ 1, 404 },
{ 4, 421 },
{ 4, 409 },
{ 4, 445 },
{ 4, 659 },
{ 4, 663 },
{ 4, 425 },
{ 4, 413 },
{ 4, 449 },
{ 4, 429 },
{ 4, 417 },
{ 4, 453 },
{ 4, 683 },
{ 4, 643 },
{ 4, 647 },
{ 4, 651 },
{ 4, 711 },
{ 4, 655 },
{ 4, 715 },
{ 4, 703 },
{ 4, 707 },
{ 4, 457 },
{ 4, 461 },
{ 4, 493 },
{ 4, 497 },
{ 4, 501 },
{ 4, 433 },
{ 4, 437 },
{ 4, 441 },
{ 4, 687 },
{ 4, 691 },
{ 4, 695 },
{ 4, 517 },
{ 4, 465 },
{ 4, 469 },
{ 4, 473 },
{ 4, 477 },
{ 4, 481 },
{ 4, 485 },
{ 4, 489 },
{ 4, 675 },
{ 4, 679 },
{ 4, 505 },
{ 4, 509 },
{ 4, 513 },
{ 4, 667 },
{ 4, 671 },
{ 4, 2 },
{ 4, 6 },
{ 4, 10 },
{ 4, 14 },
{ 4, 18 },
{ 4, 22 },
{ 4, 26 },
{ 4, 30 },
{ 4, 34 },
{ 4, 38 },
{ 4, 42 },
{ 4, 46 },
{ 4, 50 },
{ 4, 54 },
{ 4, 58 },
{ 4, 62 },
{ 4, 66 },
{ 4, 70 },
{ 4, 74 },
{ 4, 78 },
{ 4, 82 },
{ 4, 86 },
{ 4, 90 },
{ 4, 94 },
{ 4, 98 },
{ 4, 102 },
{ 4, 106 },
{ 4, 110 },
{ 4, 114 },
{ 4, 118 },
{ 4, 122 },
{ 4, 126 },
{ 4, 130 },
{ 4, 134 },
{ 4, 138 },
{ 4, 142 },
{ 4, 146 },
{ 4, 150 },
{ 4, 154 },
{ 4, 158 },
{ 4, 162 },
{ 4, 166 },
{ 4, 170 },
{ 4, 174 },
{ 4, 178 },
{ 4, 182 },
{ 4, 186 },
{ 4, 190 },
{ 4, 194 },
{ 4, 198 },
{ 4, 202 },
{ 4, 206 },
{ 4, 210 },
{ 4, 214 },
{ 4, 218 },
{ 4, 222 },
{ 4, 226 },
{ 4, 230 },
{ 4, 234 },
{ 4, 238 },
{ 4, 242 },
{ 4, 246 },
{ 4, 250 },
{ 4, 254 },
{ 4, 258 },
{ 4, 262 },
{ 4, 266 },
{ 4, 270 },
{ 4, 274 },
{ 4, 521 },
{ 4, 525 },
{ 4, 537 },
{ 4, 533 },
{ 4, 545 },
{ 4, 541 },
{ 4, 699 },
{ 4, 639 },
{ 4, 631 },
{ 4, 635 },
{ 1, 407 },
{ 1, 406 },
{ 1, 408 },
{ 2, 549 },
{ 2, 551 },
{ 2, 553 },
{ 2, 555 },
{ 2, 557 },
{ 2, 559 },
{ 2, 561 },
{ 2, 563 },
{ 2, 565 },
{ 2, 567 },
{ 2, 569 },
{ 2, 571 },
{ 2, 573 },
{ 2, 575 },
{ 2, 577 },
{ 2, 579 },
{ 2, 581 },
{ 2, 583 },
{ 2, 585 },
{ 2, 587 },
{ 2, 589 },
{ 2, 591 },
{ 2, 593 },
{ 2, 595 },
{ 2, 597 },
{ 2, 599 },
{ 2, 601 },
{ 2, 611 },
{ 2, 603 },
{ 2, 609 },
{ 2, 613 },
{ 2, 615 },
{ 2, 617 },
{ 2, 619 },
{ 2, 623 }
};
static bool publish_sensor_data(const char* command, const Json::Value payload)
{
Json::StreamWriterBuilder builder;
builder["indentation"] = "";
builder["emitUTF8"] = true;
Json::Value jsonRoot;
jsonRoot["cmd"] = command;
char str[128];
#ifdef NOPOLL_64BIT_PLATFORM
snprintf(str, sizeof(str), "%ld", snowflake_next_id());
#else
snprintf(str, sizeof(str), "%lld", snowflake_next_id());
#endif
jsonRoot["cmdId"] = str;
Json::Int64 mtime = (Json::Int64)time(NULL);
mtime *= 1000;
jsonRoot["time"] = mtime;
jsonRoot["data"] = payload;
std::string outputConfig = Json::writeString(builder, jsonRoot);
g_conn->sendMsg(outputConfig);
return true;
}
static WORD GetUnitYCRegisterAddr(int uid, int point)
{
struUnit* pUnit;
struUnitYC* pYC;
if (uid < 0 || uid >= UNIT_NUM) return (WORD)65535;
pUnit = &config.units[uid];
if (pUnit->yccount <= 0) return (WORD)65535;
if (point < 0 || point >= pUnit->yccount) return (WORD)65535;
pYC = &pUnit->ycs[point];
return (MAKEWORD(pYC->m_param[0], pYC->m_param[1]));
}
static WORD GetUnitYXRegisterAddr(int uid, int point)
{
struUnit* pUnit;
struUnitYX* pYX;
if (uid < 0 || uid >= UNIT_NUM) return (WORD)65535;
pUnit = &config.units[uid];
if (pUnit->yxcount <= 0) return (WORD)65535;
if (point < 0 || point >= pUnit->yxcount) return (WORD)65535;
pYX = &pUnit->yxs[point];
return (MAKEWORD(pYX->m_param[0], pYX->m_param[1]));
}
static BYTE GetUnitYXDataPos(int uid, int point)
{
struUnit* pUnit;
struUnitYX* pYX;
if (uid < 0 || uid >= UNIT_NUM) return (BYTE)0;
pUnit = &config.units[uid];
if (pUnit->yxcount <= 0) return (BYTE)0;
if (point < 0 || point >= pUnit->yxcount) return (BYTE)0;
pYX = &pUnit->yxs[point];
return (pYX->m_param[3]);
}
static BOOLEAN GetYCValue(const int order, const FIELDDES* fields, const char* pData, LONG& value)
{
if (pData == NULL) return FALSE;
if (fields == NULL) return FALSE;
if (order < 0 || order >= (int)(sizeof(m_datalen_mbaddr) / sizeof(m_datalen_mbaddr[0]))) return FALSE;
int start = fields[order].start;
if (fields[order].length == sizeof(DWORD))
{ //4字节
value = *(LONG *)(pData + start);
return TRUE;
}
else if (fields[order].length == sizeof(WORD))
{
short tmp = *(short *)(pData + start);
value = (LONG)tmp;
return TRUE;
}
return FALSE;
}
static BOOLEAN GetYXValue(const int order, const FIELDDES* fields, const char* pData, const int pos, BOOLEAN& value)
{
if (pData == NULL) return FALSE;
if (fields == NULL) return FALSE;
if (pos < 0 || pos >= 16) return FALSE;
if (order < 0 || order >= (int)(sizeof(m_datalen_mbaddr) / sizeof(m_datalen_mbaddr[0]))) return FALSE;
int start = fields[order].start;
if (fields[order].length == sizeof(WORD))
{
WORD tmp = *(WORD *)(pData + start);
WORD nTemp = 0x0001;
nTemp <<= pos;
if (tmp & nTemp) value = TRUE;
else value = FALSE;
return TRUE;
}
return FALSE;
}
static bool publishhistoryHighSpeedData(const int uid, const QWORD dt, const Json::Value values)
{
if (uid < 0 || uid >= UNIT_NUM) return false;
Json::Value root;
if (values.size()) {
root["dataTime"] = (Json::Int64)dt;
root["deviceId"] = static_units[uid].deviceId;
root["values"] = values;
return publish_sensor_data("historyHighSpeedData", root);
}
return false;
}
#ifndef USE_NOPOLL_WEBSOCKET
static bool publishhistoryLowSpeedData(const int uid, const QWORD dt, const Json::Value values)
#else
static bool publishhistoryLowSpeedData(const noPollConn* conn, const int uid, const QWORD dt, const Json::Value values)
#endif
{
if (uid < 0 || uid >= UNIT_NUM) return false;
Json::Value root;
if (values.size()) {
root["dataTime"] = (Json::Int64)(dt / 1000 * 1000); //取整
root["deviceId"] = static_units[uid].deviceId;
root["values"] = values;
#ifndef USE_NOPOLL_WEBSOCKET
return publish_sensor_data("historyLowSpeedData", root);
#else
return publish_sensor_data(conn, "historyLowSpeedData", root);
#endif
}
return false;
}
#if 0
static int ftpget(const char* remote, const char* local, const char* user, const char* pwd, const long timeout = 3, struct memory* chunk = NULL)
{
//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);
CURLcode ret = CURLE_GOT_NOTHING;
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_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)chunk);
curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L); // Optional: depending on your FTP server
ret = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_global_cleanup();
return ret;
}
#endif
static void* ryftp_process(void* param)
{
if (param == NULL) return ((void*)0);
CHostADSBFProcess* mbt = (CHostADSBFProcess *)param;
//获取此协议配置里面的ftp信息
char remote[512];
//char name[512];
//默认参数,或是通过协议配置获取
char user[128] = "administrator";
char password[128] = "123456";
char ipaddress[128] = "127.0.0.1";
char remotePath[128] = "Hard Disk2/data/rtdatalog";
//char pathName[128] = "./";
char processName[128];
snprintf(processName, sizeof(processName), "%s", mbt->m_pidName.c_str());
//配置远方路径
char* escaped_string = escape_char_in_string(mbt->m_remotePath, ' ');
if (escaped_string == NULL)
{
vLog(LOG_DEBUG, "%s 路径转义错误!\n", processName);
return ((void*)0);
}
snprintf(remotePath, sizeof(remotePath), "%s", escaped_string);
free(escaped_string);
#if 0
//根据协议创s建一个本地协议目录
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);
#endif
//配置的用户名和密码
snprintf(user, sizeof(user), "%s", mbt->m_user);
snprintf(password, sizeof(password), "%s", mbt->m_password);
//配置ip地址
memset(ipaddress, '\0', sizeof(ipaddress));
snprintf(ipaddress, sizeof(ipaddress), "%s", mbt->getRemoteIp());
for (int i = 0; i < (int)(sizeof(m_datalen_mbaddr) / sizeof(m_datalen_mbaddr[0])); i++) {
m_datalen2mbaddr_map.insert(datalen2mbaddrmap::value_type(m_datalen_mbaddr[i].address, i + 1));
}
//struRYDeviceData t_data;
FIELDDES fields[1024];
calcFields(fields);
//判断是否链接单元
int uid = mbt->GetUnitID(0); //默认只接一个设备
if (uid < 0 || uid >= UNIT_NUM) return ((void*)0);
datatypemap highspeedmap;
datatypemap lowspeedmap;
datatypeposmap yxdatamap;
int yccount = GetUnitYCCount(uid);
for (int i = 0; i < yccount; i++) {
//根据遥测参数配置寄存器,获取高频数据寄存器
WORD register_addr = GetUnitYCRegisterAddr(uid, i);
if (GetUnitYCType(uid, i)) {
if (m_datalen2mbaddr_map.find(register_addr) != m_datalen2mbaddr_map.end()) {
highspeedmap.insert(datatypemap::value_type(i, m_datalen2mbaddr_map[register_addr])); //point-配置的序号order-数据文件序号
//vLog(LOG_DEBUG, "register_addr is: %d, point is: %d, and order is: %d\n", register_addr, i, m_datalen2mbaddr_map[register_addr]);
}
} else {
if (m_datalen2mbaddr_map.find(register_addr) != m_datalen2mbaddr_map.end()) {
lowspeedmap.insert(datatypemap::value_type(i, m_datalen2mbaddr_map[register_addr])); //point-配置的序号order-数据文件序号
//vLog(LOG_DEBUG, "register_addr is: %d, point is: %d, and order is: %d\n", register_addr, i, m_datalen2mbaddr_map[register_addr]);
}
}
}
int yxcount = GetUnitYXCount(uid);
for (int i = 0; i < yxcount; i++) {
//根据遥测参数配置寄存器,获取高频数据寄存器
WORD register_addr = GetUnitYXRegisterAddr(uid, i);
BYTE data_pos = GetUnitYXDataPos(uid, i);
//vLog(LOG_DEBUG, "register_addr is: %d, pos is: %d.\n", register_addr, data_pos);
struDataPos pos;
if (m_datalen2mbaddr_map.find(register_addr) != m_datalen2mbaddr_map.end()) {
pos.point = m_datalen2mbaddr_map[register_addr];
pos.pos = data_pos;
yxdatamap.insert(datatypeposmap::value_type(i, pos)); //point-配置的序号order-数据文件序号
//vLog(LOG_DEBUG, "register_addr is: %d, point is: %d, and order is: %d\n", register_addr, i, m_datalen2mbaddr_map[register_addr]);
}
}
//根据实际配置表将
WORD ftpget_retry_count = 0;
BOOLEAN bReadCurrentFile = TRUE; //读取当前文件标识
while (TRUE) {
sleep(1); //每秒执行一次
if (!mbt->m_bFtpRun) break;
//ftp获取文件
if (mbt->m_iv == 1) {
//文件目录无效
continue;
}
if (bReadCurrentFile)
{ //读取当前文件
//vLog(LOG_DEBUG, "读取当前文件.\n");
//snprintf(name, sizeof(name), "%s/%d", pathName, mbt->m_currentFileNo);
snprintf(remote, sizeof(remote), "ftp://%s/%s/%d/%d", ipaddress, remotePath, mbt->m_currentDirNo, mbt->m_currentFileNo);
}
else
{ //读取未读的文件
//vLog(LOG_DEBUG, "读取未读的文件.\n");
//snprintf(name, sizeof(name), "%s/%d", pathName, mbt->m_lastReadFileNo);
snprintf(remote, sizeof(remote), "ftp://%s/%s/%d/%d", ipaddress, remotePath, mbt->m_lastReadDirNo, mbt->m_lastReadFileNo);
}
struct memory chunk = {0}; // For storing the downloaded data
//vLog(LOG_DEBUG, "start to read %s\n", remote);
CURLcode result = ftpget(remote, user, password, 3, &chunk);
//vLog(LOG_DEBUG, "%s ftpget result is: %d,%s\n", processName, result, curl_easy_strerror(result));
if (result == CURLE_OK) {
//成功,处理文件
vLog(LOG_DEBUG, "%s get %s to local memory, with name: %s, and password: %s okay, and file length is: %d.\n", processName, remote, user, password, chunk.size);
config.units[uid].value &= ~0x02;
ftpget_retry_count = 0;
if (chunk.size <= (int)(sizeof(struRYDeviceData) << 5)) {
vLog(LOG_DEBUG, "%s PLC文件生成未完成\n", processName);
continue;
}
struRYDeviceData *data = (struRYDeviceData *)chunk.response;
int uid = mbt->GetCurUnitID();
for (int i = 0; i < 250; i++, data++) { //每个文件有250个数据块
QLONG unix_time = filetime_to_unix(data->localtime);
DWORD localtime = ((unix_time / 1000) - 28800L);
DWORD millisec = unix_time % 1000;
unix_time = localtime; unix_time *= 1000;
unix_time += millisec;
#if 0
unionCP56Time st;
st = Time_ttounionCP56Time(localtime);
vLog(LOG_DEBUG, "data<%d> time is: %04d/%02d/%02d %02d:%02d:%02d.%03d\n", \
i, \
st.year + 2000, st.month, st.dayofmonth, \
st.hour, st.minute, st.millisecond/1000, st.millisecond%1000);
#endif
//如何将结构化数据传入,且快速获取
Json::Value highspeedvalues;
for (datatypemap::iterator it = highspeedmap.begin(); it != highspeedmap.end(); it++) {
//获取数据
LONG dvalue;
int order = it->first;
int point = it->second;
if (GetYCValue(point, fields, (const char *)data, dvalue)) {
if (GetUnitYCIsFloat(uid, order)) {
highspeedvalues[(const char *)config.units[uid].ycs[order].name] = GetUnitYCRealFromValue(uid, order, dvalue);
} else {
highspeedvalues[(const char *)config.units[uid].ycs[order].name] = dvalue;
}
} else {
highspeedvalues[(const char *)config.units[uid].ycs[order].name] = 0.0f;
}
}
#ifndef USE_NOPOLL_WEBSOCKET
publishhistoryHighSpeedData(uid, unix_time, highspeedvalues);
#else
publishhistoryHighSpeedData(g_conn, uid, unix_time, highspeedvalues);
#endif
if (i % 25 == 0) { //40ms一个值每25次位1s
Json::Value lowspeedvalues;
for (datatypemap::iterator it = lowspeedmap.begin(); it != lowspeedmap.end(); it++) {
//获取数据
LONG dvalue;
int order = it->first;
int point = it->second;
if (GetYCValue(point, fields, (const char *)data, dvalue)) {
//fprintf(stderr, "get<%d> value is: %d.\n", point, dvalue);
if (GetUnitYCIsFloat(uid, order)) {
lowspeedvalues[(const char *)config.units[uid].ycs[order].name] = GetUnitYCRealFromValue(uid, order, dvalue);
} else {
lowspeedvalues[(const char *)config.units[uid].ycs[order].name] = dvalue;
}
} else {
lowspeedvalues[(const char *)config.units[uid].ycs[order].name] = 0.0f;
}
}
for (datatypeposmap::iterator it = yxdatamap.begin(); it != yxdatamap.end(); it++) {
BOOLEAN bvalue;
int order = it->first;
int point = it->second.point;
int pos = it->second.pos;
//vLog(LOG_DEBUG, "start to get point is: %d, pos is: %d\n", point, pos);
if (GetYXValue(point, fields, (const char *)data, pos, bvalue)) {
lowspeedvalues[(const char *)config.units[uid].yxs[order].name] = (int)bvalue;
} else {
lowspeedvalues[(const char *)config.units[uid].yxs[order].name] = 0;
}
}
#ifndef USE_NOPOLL_WEBSOCKET
publishhistoryLowSpeedData(uid, unix_time, lowspeedvalues);
#else
publishhistoryLowSpeedData(g_conn, uid, unix_time, lowspeedvalues);
#endif
}
}
if (chunk.response) free(chunk.response);
if (bReadCurrentFile) { //读取的是当前文件
mbt->m_lastFileNo = mbt->m_currentFileNo;
mbt->m_currentFileNo++;
if ((mbt->m_currentFileNo - mbt->m_currentDirStartFileNo) % 1000 == 0) {
//一个文件夹最多存放1000个文件, mbt->m_currentFileNo = 0;
mbt->m_currentDirNo++;
mbt->m_currentDirStartFileNo = mbt->m_currentFileNo;
}
} else { //读取的是未读历史文件
mbt->m_lastReadFileNo++;
if ((mbt->m_lastReadFileNo - mbt->m_lastReadDirStartFileNo) % 1000 == 0) {
//一个文件夹最多存放1000个文件, mbt->m_currentFileNo = 0;
mbt->m_lastReadDirNo++;
}
if (mbt->m_curStartDirNo <= mbt->m_lastReadDirNo && mbt->m_curStartFileNo <= mbt->m_lastReadFileNo) {
vLog(LOG_DEBUG, "%s a已读取完成所有未读的文件。\n", processName);
mbt->m_bHaveUnReadFile = FALSE;
}
}
bReadCurrentFile = TRUE;
} else if (result == CURLE_REMOTE_FILE_NOT_FOUND) {
//文件不存在尝试60次1分钟正常情况下PLC10s生成一个文件
//vLog(LOG_DEBUG, "文件不存在, ftpget_retry_count is: %d\n", ftpget_retry_count);
ftpget_retry_count++;
if (ftpget_retry_count >= 60) {
//重新通过modbus程序获取文件夹和最新文件信息
mbt->m_iv = 0;
mbt->m_currentDirNo = -1;
mbt->m_currentFileNo = -1;
config.units[uid].value |= 0x02; //
}
//此处空闲读取未读的文件
if (mbt->m_bHaveUnReadFile) {
bReadCurrentFile = FALSE;
}
} else if (result == CURLE_REMOTE_ACCESS_DENIED) {
vLog(LOG_DEBUG, "%s b已读取完成所有未读的文件。\n", processName);
mbt->m_bHaveUnReadFile = FALSE;
bReadCurrentFile = TRUE;
}
}
pthread_exit(0);
return ((void*)0);
}
CHostADSBFProcess::CHostADSBFProcess()
{
m_adsDatas[0].inuse = FALSE;
m_adsDatas[1].inuse = FALSE;
m_adsDatas[2].inuse = FALSE;
m_adsDatas[3].inuse = FALSE;
m_adsDatas[0].adsDataMemAddr = 65535;
m_adsDatas[1].adsDataMemAddr = 65535;
m_adsDatas[2].adsDataMemAddr = 65535;
m_adsDatas[3].adsDataMemAddr = 65535;
m_localIp = "192.168.0.1"; //本机IP地址
m_localNetId = "192.168.0.1.1.1"; //本机IP地址
m_remoteIp = "192.168.0.2"; //PLC设备ip地址
m_remoteNetId = "192.168.0.2.1.1";
//websocket接口
m_cpid = 0;
//目录无效
m_iv = 1;
m_currentDirNo = -1; //当前目录编号
m_currentFileNo = -1; //当前文件编号
m_lastDirNo = -1; //上一目录编号
m_lastFileNo = -1; //上一文件编号
m_bFtpRun = FALSE;
}
CHostADSBFProcess::~CHostADSBFProcess()
{
if (m_bHaveFTP)
{
m_bFtpRun = FALSE;
vLog(LOG_DEBUG, "保存本协议读取到的那个目录和文件\n");
char fileName[260];
snprintf(fileName, sizeof(fileName), "hostads_%d.mem", GetCurID());
FILE *pf = fopen(fileName, "w+");
if (pf)
{
fwrite(&m_currentDirNo, sizeof(LONG), 1, pf);
fwrite(&m_currentFileNo, sizeof(LONG), 1, pf);
fwrite(&m_currentDirStartFileNo, sizeof(LONG), 1, pf);
fclose(pf);
}
char name[16];
memset(name, '\0', sizeof(name));
if (pthread_getname_np(m_cpid, name, sizeof(name)) != 0)
{
memset(name, '\0', sizeof(name));
}
vLog(LOG_DEBUG, "waiting for child thread [%s] destroy.\n", (name[0] != '\0') ? name : "unknow");
pthread_join(m_cpid, NULL);
vLog(LOG_DEBUG, "child protocol thread [%s] is destroyed.\n", (name[0] != '\0') ? name : "unknow");
}
#if 0
if (m_threadRun) {
m_threadRun = FALSE;
m_startup.join();
}
#endif
}
BOOLEAN CHostADSBFProcess::calc(void)
{
int n, uid;
uid = GetCurUnitID();
if (uid < 0 || uid >= UNIT_NUM) return FALSE;
m_adsDatas[0].inuse = FALSE;
m_adsDatas[1].inuse = FALSE;
m_adsDatas[2].inuse = FALSE;
m_adsDatas[3].inuse = FALSE;
m_adsDatas[0].adsDataMemAddr = 65535;
m_adsDatas[1].adsDataMemAddr = 65535;
m_adsDatas[2].adsDataMemAddr = 65535;
m_adsDatas[3].adsDataMemAddr = 65535;
//需要给单元添加一个是否有ftp数据的标识
if (m_bHaveFTP) config.units[uid].state |= 0x20; //存在ftp标识
int yccount, ymcount, yxcount;
yccount = GetUnitYCCount(uid);
ymcount = GetUnitYMCount(uid);
yxcount = GetUnitYXCount(uid);
//vLog(LOG_DEBUG, "unit %d, yc count is: %d, and yx count is: %d\n", uid, yccount, yxcount);
BYTE params[MAX_UNIT_POINT_PARAM_SIZE];
BYTE* pData = params;
WORD registerAddr = 0;
BYTE value_type = 0;
for (n = 0; n < yccount; n++)
{
pData = GetUnitYCParamByPoint(uid, n);
if (pData[4] == 1) continue;
registerAddr = MAKEWORD(pData[0], pData[1]);
if (registerAddr < DATA_BLOCK_BOUNDARY)
{
if (!m_adsDatas[0].inuse) m_adsDatas[0].inuse = TRUE;
if (registerAddr < m_adsDatas[0].adsDataMemAddr) m_adsDatas[0].adsDataMemAddr = registerAddr;
if (m_adsDatas[0].adsDataBlocks.find(registerAddr) == m_adsDatas[0].adsDataBlocks.end()) {
m_adsDatas[0].adsDataBlocks.insert(register2typemap::value_type(registerAddr, REGISTER_DATA_TYPE_YC));
} else {
//vLog(LOG_WARN, "遥测测点配置了相同的寄存器地址\n");
}
}
else
{
if (!m_adsDatas[1].inuse) m_adsDatas[1].inuse = TRUE;
if (registerAddr < m_adsDatas[1].adsDataMemAddr) m_adsDatas[1].adsDataMemAddr = registerAddr;
if (m_adsDatas[1].adsDataBlocks.find(registerAddr) == m_adsDatas[1].adsDataBlocks.end()) {
m_adsDatas[1].adsDataBlocks.insert(register2typemap::value_type(registerAddr, REGISTER_DATA_TYPE_YC));
} else {
//vLog(LOG_WARN, "遥测测点配置了相同的寄存器地址\n");
}
}
}
for (n = 0; n < ymcount; n++)
{
pData = GetUnitYMParamByPoint(uid, n);
if (pData[4] == 1) continue;
registerAddr = MAKEWORD(pData[0], pData[1]);
if (registerAddr < DATA_BLOCK_BOUNDARY)
{
if (!m_adsDatas[0].inuse) m_adsDatas[0].inuse = TRUE;
if (registerAddr < m_adsDatas[0].adsDataMemAddr) m_adsDatas[0].adsDataMemAddr = registerAddr;
if (m_adsDatas[0].adsDataBlocks.find(registerAddr) == m_adsDatas[0].adsDataBlocks.end()) {
m_adsDatas[0].adsDataBlocks.insert(register2typemap::value_type(registerAddr, REGISTER_DATA_TYPE_YM));
} else {
//vLog(LOG_WARN, "遥脉测点配置了相同的寄存器地址\n");
}
}
else
{
if (!m_adsDatas[1].inuse) m_adsDatas[1].inuse = TRUE;
if (registerAddr < m_adsDatas[1].adsDataMemAddr) m_adsDatas[1].adsDataMemAddr = registerAddr;
if (m_adsDatas[1].adsDataBlocks.find(registerAddr) == m_adsDatas[1].adsDataBlocks.end()) {
m_adsDatas[1].adsDataBlocks.insert(register2typemap::value_type(registerAddr, REGISTER_DATA_TYPE_YM));
} else {
//vLog(LOG_WARN, "遥脉测点配置了相同的寄存器地址\n");
}
}
}
for (n = 0; n < yxcount; n++)
{
pData = GetUnitYXParamByPoint(uid, n);
if (pData[4] == 1) continue;
registerAddr = MAKEWORD(pData[0], pData[1]);
value_type = pData[2];
if (registerAddr < DATA_BLOCK_BOUNDARY)
{
if (!m_adsDatas[0].inuse) m_adsDatas[0].inuse = TRUE;
if (registerAddr < m_adsDatas[0].adsDataMemAddr) m_adsDatas[0].adsDataMemAddr = registerAddr;
if (m_adsDatas[0].adsDataBlocks.find(registerAddr) == m_adsDatas[0].adsDataBlocks.end()) {
m_adsDatas[0].adsDataBlocks.insert(register2typemap::value_type(registerAddr, REGISTER_DATA_TYPE_YX_BYTE + value_type));
}
}
else
{
if (!m_adsDatas[1].inuse) m_adsDatas[1].inuse = TRUE;
if (registerAddr < m_adsDatas[1].adsDataMemAddr) m_adsDatas[1].adsDataMemAddr = registerAddr;
if (m_adsDatas[1].adsDataBlocks.find(registerAddr) == m_adsDatas[1].adsDataBlocks.end()) {
m_adsDatas[1].adsDataBlocks.insert(register2typemap::value_type(registerAddr, REGISTER_DATA_TYPE_YX_BYTE + value_type));
}
}
}
return TRUE;
}
void CHostADSBFProcess::tryStartup()
{
m_turbine = NULL;
pthread_setname_np(pthread_self(), m_pidName.c_str());
while (m_threadRun) {
if (m_turbine == NULL) {
SetLocalAmsNetId(AmsNetId(m_localNetId));
m_turbine = new AdsDevice{m_remoteIp, AmsNetId(m_remoteNetId), m_remotePort};
const auto state = m_turbine->GetState();
vLog(LOG_DEBUG, "%s ADS state: %d devState: %d\n", m_pidName.c_str(), (uint16_t)state.ads, (uint16_t)state.device);
if ((uint16_t)state.ads >= ADSSTATE::ADSSTATE_MAXSTATES || (uint16_t)state.device >= ADSSTATE::ADSSTATE_MAXSTATES)
{
vLog(LOG_DEBUG, "read device state error.\n");
long ret = AddRemoteRoute(m_remoteIp, m_localNetId, m_localIp, std::string("isoftstone"), std::string("admin"), std::string("admin"));
vLog(LOG_DEBUG, "bbb %s add route return value is: %d\n", m_pidName.c_str(), ret);
delete m_turbine;
m_turbine = NULL;
}
} else {
if (m_turbine->IsConnected()) continue;
delete m_turbine;
m_turbine = NULL;
}
sleep(5);
}
}
BOOLEAN CHostADSBFProcess::OnPreCreate(int id)
{
if (!CProcess::OnPreCreate(id)) return FALSE;
if (!GetOption(&m_nOptions, sizeof(m_nOptions)))
{
vLog(LOG_DEBUG, "润阳ADS读取配置错误。");
return FALSE;
}
char ipaddress[32];
m_pidName = std::string(GetCurProcessName());
//本机IP和netid
memset(ipaddress, '\0', sizeof(ipaddress));
inet_ntop(AF_INET, &m_nOptions.net.bind_addr, ipaddress, 16);
m_localIp = std::string(ipaddress);
m_localNetId = m_localIp + std::string(".1.1");
//目标IP和netid
memset(ipaddress, '\0', sizeof(ipaddress));
inet_ntop(AF_INET, &m_nOptions.net.target_addr, ipaddress, 16);
m_remoteIp = std::string(ipaddress);
m_remoteNetId = m_remoteIp + std::string(".1.1");
//目标端口
m_remotePort = m_nOptions.net.target_port;
m_bHaveFTP = m_nOptions.bHaveFTP;
calc();
//vLog(LOG_DEBUG, "%s local ip is: %s, netid is: %s, remote ip is: %s, and netid is: %s\n", m_pidName.c_str(), m_localIp.c_str(), m_localNetId.c_str(), m_remoteIp.c_str(), m_remoteNetId.c_str());
m_turbine = NULL;
m_bRouteAdded = FALSE;
SetLocalAmsNetId(AmsNetId(m_localNetId));
#if 0
m_threadRun = TRUE;
m_startup = std::thread(&CHostADSBFProcess::tryStartup, this);
#endif
if (m_bHaveFTP)
{
snprintf(m_user, sizeof(m_user), "%s", m_nOptions.ftp.user);
snprintf(m_password, sizeof(m_password), "%s", m_nOptions.ftp.password);
snprintf(m_remotePath, sizeof(m_remotePath), "%s", m_nOptions.ftp.remotePath);
snprintf(m_localPath, sizeof(m_localPath), "%s", m_nOptions.ftp.localPath);
//读取文件
m_lastReadDirNo = 1;
m_lastReadFileNo = 1;
m_lastReadDirStartFileNo = 1;
m_bHaveUnReadFile = TRUE;
char fileName[260];
snprintf(fileName, sizeof(fileName), "hostads_%d.mem", GetCurID());
FILE *pf = fopen(fileName, "rb");
if (pf)
{
fread(&m_lastReadDirNo, sizeof(LONG), 1, pf);
fread(&m_lastReadFileNo, sizeof(LONG), 1, pf);
fread(&m_lastReadDirStartFileNo, sizeof(LONG), 1, pf);
fclose(pf);
}
//启动后创建ftp线程
if (m_cpid <= 0) {
m_bFtpRun = TRUE;
vLog(LOG_DEBUG, "ads 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_cpid, &attr, ryftp_process, this) < 0) {
vLog(LOG_ERROR, "ads create ryftp_process error(%d,%s).\n", errno, strerror(errno));
return TRUE;
}
char name[17];
snprintf(name, 16, "%s_ftp", m_pidName.c_str());
pthread_setname_np(m_cpid, name);
pthread_attr_destroy(&attr);
}
}
return TRUE;
}
BOOLEAN CHostADSBFProcess::Run(void)
{
if (!CProcess::Run()) return FALSE;
return TRUE;
}
BOOLEAN CHostADSBFProcess::OnTimer(void)
{
if (!CProcess::OnTimer()) return FALSE;
BOOLEAN sec_changed = FALSE;
if (last_sec != system32.timers)
{
last_sec = system32.timers;
sec_changed = TRUE;
}
if (sec_changed)
{
if (m_turbine == NULL) {
#if 0
m_turbine = new AdsDevice{m_remoteIp, AmsNetId(m_remoteNetId), m_remotePort};
const auto state = m_turbine->GetState();
if ((uint16_t)state.ads >= ADSSTATE::ADSSTATE_MAXSTATES || (uint16_t)state.device >= ADSSTATE::ADSSTATE_MAXSTATES)
{
vLog(LOG_DEBUG, "read device state error.\n");
long ret = AddRemoteRoute(m_remoteIp, m_localNetId, m_localIp, std::string("isoftstone"), std::string("admin"), std::string("admin"));
vLog(LOG_DEBUG, "bbb %s add route return value is: %d\n", m_pidName.c_str(), ret);
delete m_turbine;
m_turbine = NULL;
}
#else
//先添加一条路由
if (m_bRouteAdded == FALSE)
{
long ret = AddRemoteRoute(m_remoteIp, m_localNetId, m_localIp, std::string("isoftstone"), std::string("admin"), std::string("admin"));
vLog(LOG_DEBUG, "%s add route(%s to %s) return value is: %d\n", m_localIp.c_str(), m_remoteIp.c_str(), m_pidName.c_str(), ret);
if (ret != 0) return TRUE;
}
m_bRouteAdded = TRUE;
//添加成功
vLog(LOG_DEBUG, "%s start to connect(%s:%d)\n", m_pidName.c_str(), m_remoteIp.c_str(), m_remotePort);
m_turbine = new AdsDevice{m_remoteIp, AmsNetId(m_remoteNetId), m_remotePort};
const auto state = m_turbine->GetState();
if ((uint16_t)state.ads >= ADSSTATE::ADSSTATE_MAXSTATES || (uint16_t)state.device >= ADSSTATE::ADSSTATE_MAXSTATES)
{
vLog(LOG_DEBUG, "%s read device state error.\n", m_pidName.c_str());
delete m_turbine;
m_turbine = NULL;
}
#endif
return TRUE;
}
if (!m_turbine->IsConnected()) return TRUE;
//try {
if (m_bHaveFTP)
{ //启动时读取一次,后面自己维护序号
if ((m_currentDirNo == -1) && (m_currentFileNo == -1))
{ //当前文件和目录都为-1程序第一次启动。需要获取ftp目录及文件ID
readFileID();
}
}
readRealData();
FeedDog();
// } catch (const AdsException& ex) {
// vLog(LOG_ERROR, "%s AdsException message: %s, remote is: %s:%d\n", m_pidName.c_str(), ex.what(), m_remoteIp.c_str(), m_remotePort);
// } catch (const std::runtime_error& ex) {
// vLog(LOG_ERROR, "%s %s\n", m_pidName.c_str(), ex.what());
// }
}
return TRUE;
}
BOOLEAN CHostADSBFProcess::readDeviceState(const AdsDevice& route)
{
const auto state = route.GetState();
vLog(LOG_DEBUG, "ADS state: %d devState: %d\n", (uint16_t)state.ads, (uint16_t)state.device);
if ((uint16_t)state.ads >= ADSSTATE::ADSSTATE_MAXSTATES && (uint16_t)state.device >= ADSSTATE::ADSSTATE_MAXSTATES)
{
return FALSE;
}
return TRUE;
}
BOOLEAN CHostADSBFProcess::readFileID()
{
int uid = GetCurUnitID();
if (uid < 0 || uid >= UNIT_NUM) return TRUE;
vLog(LOG_DEBUG, "%s here read file info\n", m_pidName.c_str());
AdsVariable <WORD> wPathInfoInvalid {*m_turbine, ".gwPathInfoInvalid"};
//vLog(LOG_DEBUG, "Read back with first value %d\n", (WORD)wPathInfoInvalid);
AdsVariable <DWORD> wCurrentFolderNo {*m_turbine, ".gwCurrentFolderNo"};
//vLog(LOG_DEBUG, "Read back with first value %d\n", (DWORD)wCurrentFolderNo);
AdsVariable <DWORD> wCurrentFileNo {*m_turbine, ".gwCurrentFileNo"};
//vLog(LOG_DEBUG, "Read back with first value %d\n", (DWORD)wCurrentFileNo);
AdsVariable <DWORD> wFirstFileNoInFolder {*m_turbine, ".gwFirstFileNoInFolder"};
//vLog(LOG_DEBUG, "Read back with first value %d\n", (DWORD)wFirstFileNoInFolder);
AdsVariable <DWORD> wFileCountInFolder {*m_turbine, ".gwFileCountInFolder"};
//vLog(LOG_DEBUG, "Read back with first value %d\n", (DWORD)wFileCountInFolder);
AdsVariable <DWORD> wFirstFolderNoRecoverable {*m_turbine, ".gwFirstFolderNoRecoverable"};
//vLog(LOG_DEBUG, "Read back with first value %d\n", (DWORD)wFirstFolderNoRecoverable);
AdsVariable <DWORD> wFirstFileNoRecoverable {*m_turbine, ".gwFirstFileNoRecoverable"};
//vLog(LOG_DEBUG, "Read back with first value %d\n", (DWORD)wFirstFileNoRecoverable);
m_iv = (WORD)wPathInfoInvalid;
if (m_iv) {
vLog(LOG_DEBUG, "路径信息无效\n");
return FALSE;
}
//当前文件夹路径名
m_currentDirNo = (DWORD)wCurrentFolderNo;
//当前文件夹下最后新文件
m_currentFileNo = (DWORD)wCurrentFileNo;
//当前目录文件开始编号
m_currentDirStartFileNo = (DWORD)wFirstFileNoInFolder;
m_curStartDirNo = m_currentDirNo; //当前开始目录
m_curStartFileNo = m_currentFileNo; //当前开始文件
//判断是否有要读取的文件
if (m_curStartDirNo <= m_lastReadDirNo && m_curStartFileNo <= m_lastReadFileNo)
{
vLog(LOG_DEBUG, "%s 不存在未读的文件。\n", m_pidName.c_str());
m_bHaveUnReadFile = FALSE;
}
else
{
m_bHaveUnReadFile = TRUE;
int dir_count = m_curStartDirNo - m_lastReadDirNo + 1;
int file_count = m_curStartFileNo - m_lastReadFileNo;
vLog(LOG_DEBUG, "%s 总共有%d个目录的%d个文件未读取。\n", m_pidName.c_str(), dir_count, file_count);
}
vLog(LOG_DEBUG, "%s 最新文件夹编号: %ld, 最新文件名编号: %ld: 最新文件夹中第一个文件的编号: %ld\n", m_pidName.c_str(), m_currentDirNo, m_currentFileNo, m_currentDirStartFileNo);
return TRUE;
}
BOOLEAN CHostADSBFProcess::readRealData()
{
int uid = GetCurUnitID();
if (uid < 0 || uid >= UNIT_NUM) return TRUE;
for (int k = 0; k < 4; k++)
{
if (!m_adsDatas[k].inuse) continue;
WORD m_adsOverviewDataMemAddr = m_adsDatas[k].adsDataMemAddr;
register2typemap m_register2type_map = m_adsDatas[k].adsDataBlocks;
BYTE buffer[1024];
BYTE *pData = buffer;
BYTE params[MAX_UNIT_POINT_PARAM_SIZE];
BYTE* pParam = params;
AdsVariable<std::array<BYTE, MAX_BLOCKF_SIZE>> turbineData {*m_turbine, ADSIGRP_IOIMAGE_RWOB, m_adsOverviewDataMemAddr};
pData = ((std::array<BYTE, MAX_BLOCKF_SIZE>)turbineData).data();
WORD registerAddr = m_adsOverviewDataMemAddr;
float f_val;
DWORD dw[2]; //双精度转换中间变量
double d_val;
DWORD bin_value;
DWORD nValue = 0;
int point;
UnitFeedDog(uid);
for (int i = 0; i < MAX_BLOCKF_SIZE;)
{
//vLog(LOG_DEBUG, "registerAddr is: %d\n", registerAddr);
if (m_register2type_map.find(registerAddr) != m_register2type_map.end())
{
int type = m_register2type_map[registerAddr];
if (type == REGISTER_DATA_TYPE_YC)
{ //遥测
point = GetUnitYCPointByParam(uid, (BYTE *)&registerAddr, 2);
if (point >= 0)
{
pParam = GetUnitYCParamByPoint(uid, point);
BYTE value_type = pParam[2]; //数据类型
BYTE sign_mark = pParam[3];
//vLog(LOG_DEBUG, "value type is: %d, ", value_type);
//32位测量值
if (0 == value_type)
{ //浮点数,高位在第一个寄存器
nValue = (DWORD)(pData[1] << 24 | pData[0] << 16 | pData[3] << 8 | pData[2]);
memcpy(&f_val, &nValue, 4);
SetUnitYC(uid, point, f_val);
registerAddr += 4; i += 4; pData += 4;
}
else if (1 == value_type)
{
nValue = (DWORD)(pData[3] << 24 | pData[2] << 16 | pData[1] << 8 | pData[0]);
memcpy(&f_val, &nValue, 4);
SetUnitYC(uid, point, f_val);
registerAddr += 4; i += 4; pData += 4;
}
//16位归一化值
else if (2 == value_type)
{
if (sign_mark == 0) nValue = (DWORD)(WORD)((pData[1] << 8) | pData[0]);
else nValue = (DWORD)(short)((pData[1] << 8) | pData[0]);
SetUnitYC(uid, point, (LONG)nValue);
//vLog(LOG_DEBUG, "value is: %d \n", nValue);
registerAddr += 2; i += 2; pData += 2;
}
else if (3 == value_type)
{ //归一化值,高位在第一个寄存器
nValue = (DWORD)(pData[1] << 24 | pData[0] << 16 | pData[3] << 8 | pData[2]);
SetUnitYC(uid, point, (LONG)nValue);
registerAddr += 2; i += 2; pData += 2;
}
else if (4 == value_type)
{ //归一化值,高位在第二个寄存器
nValue = (DWORD)(pData[3] << 24 | pData[2] << 16 | pData[1] << 8 | pData[0]);
SetUnitYC(uid, point, (LONG)nValue);
registerAddr += 4; i += 4; pData += 4;
//vLog(LOG_DEBUG, "value is: %d\n", nValue);
}
else if (5 == value_type)
{ //小端系统浮点值
nValue = (DWORD)(pData[3] << 24 | pData[2] << 16 | pData[1] << 8 | pData[0]);
memcpy(&f_val, &nValue, 4);
SetUnitYC(uid, point, f_val);
//vLog(LOG_DEBUG, "value is: %f\n", f_val);
registerAddr += 4; i += 4; pData += 4;
}
else if (6 == value_type)
{ //32位bcd数据高位在第一个寄存器
nValue = (DWORD)((pData[1] << 24) | (pData[0] << 16) | (pData[3] << 8) | pData[2]);
bin_value = bcd_to_int((const BYTE*)&nValue, sizeof(DWORD));
SetUnitYC(uid, point, (LONG)bin_value);
registerAddr += 4; i += 4; pData += 4;
}
else if (7 == value_type)
{ //32位bcd数据高位在第二个寄存器
nValue = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
bin_value = bcd_to_int((const BYTE*)&nValue, sizeof(DWORD));
SetUnitYC(uid, point, (LONG)bin_value);
registerAddr += 4; i += 4; pData += 4;
}
else if (8 == value_type)
{ //16位BCD
if (sign_mark == 0) nValue = (DWORD)(WORD)((pData[1] << 8) | pData[0]);
else nValue = (DWORD)(short)((pData[1] << 8) | pData[0]);
nValue = bcd_to_int((const BYTE*)&nValue, sizeof(WORD));
SetUnitYC(uid, point, (LONG)nValue);
registerAddr += 2; i += 2; pData += 2;
//vLog(LOG_DEBUG, "value is: %d\n", nValue);
}
else if (9 == value_type)
{ //
if (sign_mark == 0) nValue = (DWORD)(BYTE)(pData[0]);
else nValue = (DWORD)(short)(pData[0]);
SetUnitYC(uid, point, (LONG)nValue);
registerAddr++; i++; pData++;
//vLog(LOG_DEBUG, "value is: %d\n", nValue);
}
else
{
registerAddr++; i++; pData++;
}
}
}
else if (type == REGISTER_DATA_TYPE_YM)
{ //遥脉
point = GetUnitYMPointByParam(uid, (BYTE *)&registerAddr, 2);
if (point >= 0)
{
pParam = GetUnitYMParamByPoint(uid, point);
BYTE value_type = pParam[2]; //数据类型
if (0 == value_type)
{ //16位无符号整型
nValue = (pData[1] << 8) | pData[0];
SetUnitYM(uid, point, nValue);
registerAddr += 2; i += 2; pData += 2;
}
else if (1 == value_type)
{ //32位无符号整型高位在第一个寄存器
nValue = (DWORD)((pData[1] << 24) | (pData[0] << 16) | (pData[3] << 8) | pData[2]);
SetUnitYM(uid, point, nValue);
registerAddr += 4; i += 4; pData += 4;
}
else if (2 == value_type)
{ //32位整型高位在第一个寄存器
nValue = (DWORD)((pData[1] << 24) | (pData[0] << 16) | (pData[3] << 8) | pData[2]);
SetUnitYM(uid, point, nValue);
registerAddr += 4; i += 4; pData += 4;
}
else if (3 == value_type)
{ //32位无符号整型高位在第二个寄存器
nValue = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
SetUnitYM(uid, point, nValue);
registerAddr += 4; i += 4; pData += 4;
}
else if (4 == value_type)
{ //32位整型高位在第二个寄存器
nValue = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
SetUnitYM(uid, point, nValue);
registerAddr += 4; i += 4; pData += 4;
}
else if (5 == value_type)
{ //32位浮点数高位在第一个寄存器
nValue = (DWORD)((pData[1] << 24) | (pData[0] << 16) | (pData[3] << 8) | pData[2]);
memcpy(&f_val, &nValue, 4);
SetUnitYM(uid, point, (DWORD)f_val);
registerAddr += 4; i += 4; pData += 4;
}
else if (6 == value_type)
{ //32位浮点数高位在第二个寄存器
nValue = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
memcpy(&f_val, &nValue, 4);
SetUnitYM(uid, point, (DWORD)f_val);
registerAddr += 4; i += 4; pData += 4;
}
else if (7 == value_type)
{ //64位浮点数高位在第一个寄存器
dw[1] = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
dw[0] = (DWORD)((pData[7] << 24) | (pData[6] << 16) | (pData[5] << 8) | pData[4]);
memcpy(&d_val, dw, 8);
SetUnitYM(uid, point, (DWORD)(d_val));
registerAddr += 8; i += 8; pData += 8;
}
else if (8 == value_type)
{
dw[0] = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
dw[1] = (DWORD)((pData[7] << 24) | (pData[6] << 16) | (pData[5] << 8) | pData[4]);
memcpy(&d_val, dw, 8);
SetUnitYM(uid, point, (DWORD)(d_val));
registerAddr += 8; i += 8; pData += 8;
}
else if (9 == value_type)
{
nValue = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
memcpy(&f_val, &nValue, 4);
SetUnitYM(uid, point, (DWORD)(f_val * 10));
registerAddr += 4; i += 4; pData += 4;
}
else
{
registerAddr++; i++; pData++;
}
}
}
else
{ //遥信
int data_bits = 8;
BYTE params[4];
params[0] = (BYTE)(registerAddr & 0xff);
params[1] = (BYTE)((registerAddr >> 8) & 0xff);
params[2] = type - REGISTER_DATA_TYPE_YX_BYTE;
if (type == REGISTER_DATA_TYPE_YX_BYTE)
{
nValue = (DWORD)pData[0];
registerAddr++; i++; pData++;
data_bits = 8;
}
else if (type == REGISTER_DATA_TYPE_YX_WORD)
{
nValue = (DWORD)((pData[1] << 8) | pData[0]);
registerAddr += 2; i += 2; pData += 2;
data_bits = 16;
}
else if (type == REGISTER_DATA_TYPE_YX_DWORD)
{
nValue = (DWORD)((pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0]);
registerAddr += 4; i += 4; pData += 4;
data_bits = 32;
}
else
{
registerAddr++; i++; pData++;
}
DWORD nTemp = 0x00000001;
for (int j = 0; j < data_bits; j++)
{
params[3] = j;
point = GetUnitYXPointByParam(uid, (BYTE *)params, 4);
if (point >= 0)
{
BOOLEAN yxVal = SPI_OFF;
if ((nValue) & nTemp)
{
yxVal = SPI_ON;
}
SetUnitYX(uid, point, yxVal);
}
nTemp <<= 1;
}
}
}
else
{
registerAddr++; i++; pData++;
}
}
}
return TRUE;
}