map/das-dn/comm/public.cpp
2024-10-21 10:53:15 +08:00

2469 lines
87 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 "public.h"
#include "soe.h"
#include "ycbw.h"
#include "yxbw.h"
#include "yklog.h"
#include "ytlog.h"
#include "process.h"
#include "iec_101_104_lib.h"
#include <signal.h>
#include <iostream>
#include <fstream>
#ifdef USE_SQLITE3
#include "KompexSQLitePrerequisites.h"
#include "KompexSQLiteDatabase.h"
#include "KompexSQLiteStatement.h"
#include "KompexSQLiteException.h"
#include "KompexSQLiteStreamRedirection.h"
#include "KompexSQLiteBlob.h"
using namespace Kompex;
#endif
#include "json.h"
#define PARAMTER_TYPE_MODBUS 1
#define PARAMTER_TYPE_104 2
#define PARAMTER_TYPE_9712 3
#define MAX_THREAD_NUM 2
#define THREAD_ID_MAIN 0
#define THREAD_ID_IDLE 1
BOOLEAN systemRunFlag = FALSE;
BOOLEAN synchronized = FALSE;
BOOLEAN zlog_inited = FALSE;
struSystem system32;
struConfig config;
struDatabase database;
CYCBW ycbw;
CYXBW yxbw;
CSOE soe;
CYKLog yklog;
CYTLog ytlog;
CProcess* procs[PROCESSES_NUM];
struUnitStatic static_units[UNIT_NUM];
struDispBuffer channelBuffer;
struMsgBuffer msgBuffer;
struNodeOption nodes;
char configpath[MAX_PATH] = "./conf"; //配置文件所在目录
char configfile[MAX_PATH] = "./conf/config.db"; //配置文件
QWORD system_timems;
noPollConn *g_conn;
Snowflake g_sf = {1, 1, 0, 0};
static eLogLevel eLevelMax = LOG_DEBUG; //LOG_DEBUG;
static const char* arszLevel2Str[] = { "NULL", "ERROR", "WARN", "INFO", "DEBUG" };
static pthread_t p_id[MAX_THREAD_NUM];
static DWORD WriteMsgRingBuff(const char *wbuff, DWORD len)
{
DWORD l;
if (msgBuffer.buf == NULL) return -1;
len = wMin(len, MAX_DISPLAY_BUFFER_SIZE - msgBuffer.save + msgBuffer.load);
/* 第一部分的拷贝:从环形缓冲区写入数据直至缓冲区最后一个地址 */
l = wMin(len, MAX_DISPLAY_BUFFER_SIZE - (msgBuffer.save & (MAX_DISPLAY_BUFFER_SIZE - 1)));
memcpy(msgBuffer.buf + (msgBuffer.save & (MAX_DISPLAY_BUFFER_SIZE - 1)), wbuff, l);
/* 如果溢出则在缓冲区头写入剩余的部分如果没溢出这句代码相当于无效 */
memcpy(msgBuffer.buf, wbuff + l, len - l);
msgBuffer.save += len;
return len;
}
DWORD ReadMsgRingBuff(char *rbuff, DWORD len)
{
DWORD l;
if (msgBuffer.buf == NULL) return -1;
len = wMin(len, msgBuffer.save - msgBuffer.load);
/* 第一部分的拷贝:从环形缓冲区读取数据直至缓冲区最后一个 */
l = wMin(len, MAX_DISPLAY_BUFFER_SIZE - (msgBuffer.load & (MAX_DISPLAY_BUFFER_SIZE - 1)));
memcpy(rbuff, msgBuffer.buf + (msgBuffer.load & (MAX_DISPLAY_BUFFER_SIZE - 1)), l);
/* 如果溢出则在缓冲区头读取剩余的部分如果没溢出这句代码相当于无效 */
memcpy(rbuff + l, msgBuffer.buf, len - l);
msgBuffer.load += len;
return len;
}
void vLog(eLogLevel eLevel, const char* szFmt, ...)
{
if (eLevel <= eLevelMax)
{
int len;
char buffer[4096]; //dlt698.45-1867可能会比较长的报文.此处避免错误
va_list args;
len = snprintf(buffer, sizeof(buffer), "%04d/%02d/%02d %02d:%02d:%02d.%03d ",\
system32.now.year+2000, system32.now.month, system32.now.dayofmonth,\
system32.now.hour, system32.now.minute, system32.now.millisecond / 1000, system32.now.millisecond % 1000);
WriteMsgRingBuff(buffer, len);
len = snprintf(buffer, sizeof(buffer), "%s: ", arszLevel2Str[eLevel]);
WriteMsgRingBuff(buffer, len);
va_start(args, szFmt);
len = vsnprintf(buffer, sizeof(buffer), szFmt, args);
va_end(args);
WriteMsgRingBuff(buffer, len);
if (zlog_inited)
{
if (eLevel == LOG_DEBUG) dzlog_debug("%s", buffer);
else if (eLevel == LOG_INFO) dzlog_info("%s", buffer);
else if (eLevel == LOG_WARN) dzlog_warn("%s", buffer);
else if (eLevel == LOG_ERROR) dzlog_error("%s", buffer);
}
}
}
int GetFileSize(const char* fname)
{
struct stat statbuf;
if (stat(fname,&statbuf) == 0)
{
return statbuf.st_size;
}
return -1;
}
const char* match_strval_idx(DWORD val, const value_string* vs, int* idx)
{
int i = 0;
if (vs)
{
while (vs[i].strptr)
{
if (vs[i].value == val)
{
*idx = i;
return(vs[i].strptr);
}
i++;
}
}
*idx = -1;
return NULL;
}
char* ep_strdup_printf(const char* fmt, ...)
{
va_list ap;
char* dst;
dst = new char[2048];
if (dst == NULL) return NULL;
memset(dst, 0, 2048);
va_start(ap, fmt);
vsnprintf(dst, 2048, fmt, ap);
va_end(ap);
return dst;
}
const char* match_strval(DWORD val, const value_string* vs)
{
int ignore_me;
return match_strval_idx(val, vs, &ignore_me);
}
const char* val_to_str(DWORD val, const value_string* vs, const char* fmt)
{
const char* ret;
if (fmt == NULL) return NULL;
ret = match_strval(val, vs);
if (ret != NULL) return ret;
return ep_strdup_printf(fmt, val);
}
void StringToHex(const char* pStr, BYTE* pData)
{
int i;
BYTE data;
int len = strlen(pStr);
char* pBuf = (char*)pStr;
for (i = 0; i < len; i++, pBuf++)
{
if (*pBuf >= '0' && *pBuf <= '9')
{
data = *pBuf - '0';
}
else if (*pBuf >= 'a' && *pBuf <= 'f')
{
data = *pBuf - 'a' + 0x0a;
}
else if (*pBuf >= 'A' && *pBuf <= 'F')
{
data = *pBuf - 'A' + 0x0a;
}
else
{
break;
}
data = data << 4;
i++, pBuf++;
if (*pBuf >= '0' && *pBuf <= '9')
{
data |= *pBuf - '0';
}
else if (*pBuf >= 'a' && *pBuf <= 'f')
{
data |= *pBuf - 'a' + 0x0a;
}
else if (*pBuf >= 'A' && *pBuf <= 'F')
{
data |= *pBuf - 'A' + 0x0a;
}
else
{
break;
}
*pData = data;
pData++;
}
}
void HexToString(const BYTE* pData, char* pStr, int count)
{
int i;
char text[16];
BYTE* pCurData = (BYTE*)pData;
strcpy(pStr, "");
for (i = 0; i < count; i++, pCurData++)
{
sprintf(text, "%02X", (int)(*pCurData));
strcat(pStr, text);
}
count = count << 1;
for (i = count-1; i > 0; i -= 2)
{
if (pStr[i] == '0' && pStr[i-1] == '0')
{
pStr[i-1] = '\0';
}
else
{
break;
}
}
if (pStr[0] == '\0')
{
strcpy(pStr, "00");
}
}
DWORD bcd_to_int(const BYTE *bcd, int length)
{
DWORD result = 0;
for (; length > 0;)
{
length--;
result *= 10;
result += (bcd[length] >> 4) & 0x0f;
result *= 10;
result += bcd[length] & 0x0f;
}
return result;
}
void int_to_bcd(int dec, BYTE *bcd, int length)
{
int i;
int temp;
for (i = length - 1; i >= 0; i--)
{
temp = dec % 100;
bcd[i] = ((temp / 10) << 4) + ((temp % 10) & 0x0F);
dec /= 100;
}
}
int ValToBuf(BYTE* buf, DWORD val, int lenth, BOOLEAN bBigEndian)
{
if (lenth <= 0) return 0;
for (int i = 0; i < lenth; i++)
{
if (bBigEndian)
{
buf[lenth - (i + 1)] = (val >> (i << 3)) & 0xff;
}
else
{
buf[i] = (val >> (i << 3)) & 0xff;
}
}
return lenth;
}
DWORD BufToVal(BYTE* buf, int lenth, BOOLEAN bBigEndian)
{
DWORD sum = 0;
if (lenth <= 0) return 0;
for (int i = 0; i < lenth; i++)
{
if (bBigEndian)
{
sum += buf[lenth - (i + 1)] << (i << 3);
}
else
{
sum += buf[i] << (i << 3);
}
}
return sum;
}
int unionCP56TimeToBuf(BYTE* buf, unionCP56Time st)
{
int len = 0;
len = ValToBuf(buf, st.millisecond, 2);
buf[len++] = st.minute;
buf[len++] = st.hour;
buf[len++] = st.dayofmonth;
buf[len++] = st.month;
buf[len++] = st.year;
return len;
}
QWORD getTimeInMs()
{
return system_timems;
}
BOOLEAN get_system_time(unionCP56Time* lpSystemTime)
{
struct timeval tv;
struct tm stru_tmp;
if (gettimeofday(&tv, NULL) < 0) return FALSE;
localtime_r(&tv.tv_sec, &stru_tmp);
lpSystemTime->millisecond = (WORD)((stru_tmp.tm_sec * 1000) + (tv.tv_usec / 1000));
lpSystemTime->minute = stru_tmp.tm_min;
lpSystemTime->hour = stru_tmp.tm_hour;
lpSystemTime->dayofmonth = stru_tmp.tm_mday;
lpSystemTime->dayofweek = stru_tmp.tm_wday;
lpSystemTime->month = stru_tmp.tm_mon + 1;
lpSystemTime->year = stru_tmp.tm_year + 1900 - 2000;
system32.timers = (DWORD)tv.tv_sec;
system_timems = ((QWORD) tv.tv_sec * 1000LL) + (tv.tv_usec / 1000);
return TRUE;
}
int write_to_hardclock()// for linux
{
FILE *fp = NULL;
fp = popen("hwclock -w","r");
if (fp == NULL) return 0;
pclose(fp);
return 1;
}
BOOLEAN set_system_time(unionCP56Time* lpSystemTime)
{
struct timeval tv;
struct tm p;
time_t temp;
if (gettimeofday(&tv, NULL) < 0)
{
vLog(LOG_ERROR, "gettimeofday error(%d,%s).\n", errno, strerror(errno));
return FALSE;
}
localtime_r(&tv.tv_sec, &p);
p.tm_year = lpSystemTime->year + 2000 - 1900;
p.tm_mon = lpSystemTime->month - 1;
p.tm_mday = lpSystemTime->dayofmonth;
p.tm_hour = lpSystemTime->hour;
p.tm_min = lpSystemTime->minute;
p.tm_sec = lpSystemTime->millisecond / 1000;
temp = mktime(&p);
tv.tv_sec = (long)temp;
tv.tv_usec = lpSystemTime->millisecond % 1000;
if (settimeofday(&tv, NULL) < 0)
{
vLog(LOG_ERROR, "settimeofday error(%d,%s).\n", errno, strerror(errno));
return FALSE;
}
vLog(LOG_DEBUG, "system synchronized!\r\n");
synchronized = TRUE;
vLog(LOG_DEBUG, "system clock synchronized! %04d/%02d/%02d %02d:%02d:%02d=>%04d/%02d/%02d %02d:%02d:%02d\n",
system32.now.year+2000, system32.now.month, system32.now.dayofmonth,
system32.now.hour, system32.now.minute, system32.now.millisecond / 1000,
lpSystemTime->year + 2000, lpSystemTime->month, lpSystemTime->dayofmonth,
lpSystemTime->hour, lpSystemTime->minute, lpSystemTime->millisecond / 1000);
return TRUE;
}
time_t unionCP56TimetoTime_t(unionCP56Time* st)
{
time_t temp;
struct timeval tv;
struct tm p;
if (gettimeofday(&tv, NULL) < 0)
{
vLog(LOG_ERROR, "gettimeofday error(%d,%s).\n", errno, strerror(errno));
return FALSE;
}
localtime_r(&tv.tv_sec, &p);
p.tm_year = st->year + 2000 - 1900;
p.tm_mon = st->month - 1;
p.tm_mday = st->dayofmonth;
p.tm_hour = st->hour;
p.tm_min = st->minute;
p.tm_sec = st->millisecond / 1000;
temp = mktime(&p);
return temp;
}
unionCP56Time Time_ttounionCP56Time(time_t st)
{
unionCP56Time ct;
struct tm stru_tmp;
localtime_r((long *)&st, &stru_tmp);
ct.millisecond = (stru_tmp.tm_sec * 1000);
ct.minute = stru_tmp.tm_min;
ct.hour = stru_tmp.tm_hour;
ct.dayofmonth = stru_tmp.tm_mday;
ct.dayofweek = stru_tmp.tm_wday;
ct.month = stru_tmp.tm_mon + 1;
ct.year = stru_tmp.tm_year + 1900 - 2000;
return ct;
}
QLONG filetime_to_unix(QLONG ft)
{
uint64_t winTime = ft;
// 将100纳秒间隔转换为毫秒
winTime /= 10000;
// 减去从1601年到1970年的毫秒数
winTime -= 11644473600000LL;
// 将毫秒转换为秒
return (winTime);
}
QWORD current_time()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
}
QWORD snowflake_next_id(void)
{
QWORD timestamp = current_time();
if (timestamp < g_sf.last_timestamp) {
return 0;
}
if (g_sf.last_timestamp == timestamp) {
g_sf.sequence = (g_sf.sequence + 1) & SEQUENCE_MASK;
if (g_sf.sequence == 0) {
while (current_time() <= g_sf.last_timestamp);
}
} else {
g_sf.sequence = 0; // reset sequence
}
g_sf.last_timestamp = timestamp;
return ((timestamp - EPOCH) << (WORKER_ID_BITS + DATA_CENTER_ID_BITS + SEQUENCE_BITS)) |
(g_sf.data_center_id << (WORKER_ID_BITS + SEQUENCE_BITS)) |
(g_sf.worker_id << SEQUENCE_BITS) |
g_sf.sequence;
}
void alarm(void)
{
}
BOOLEAN InitializeMemory(void)
{
int i, j;
synchronized = FALSE;
systemRunFlag = FALSE;
memset(&system32, 0, sizeof(system32));
memset(&config, 0, sizeof(config));
memset(&database, 0, sizeof(database));
memset(procs, 0, sizeof(procs));
memset(&channelBuffer, 0, sizeof(channelBuffer));
memset(&msgBuffer, 0, sizeof(msgBuffer));
memset(&nodes, 0, sizeof(nodes));
// memset(units_state, 0, sizeof(units_state)); //为UI添加专用单元状态
database.yxs = new struYX[DATABASE_YX_NUM];
if (database.yxs == NULL) return FALSE;
memset(database.yxs, 0, sizeof(struYX) * DATABASE_YX_NUM);
database.ycs = new struYC[DATABASE_YC_NUM];
if (database.ycs == NULL) return FALSE;
memset(database.ycs, 0, sizeof(struYC) * DATABASE_YC_NUM);
database.yms = new struYM[DATABASE_YM_NUM];
if (database.yms == NULL) return FALSE;
memset(database.yms, 0, sizeof(struYM) * DATABASE_YM_NUM);
database.yks = new struYK[DATABASE_YK_NUM];
if (database.yks == NULL) return FALSE;
memset(database.yks, 0, sizeof(struYK) * DATABASE_YK_NUM);
database.yts = new struYT[DATABASE_YT_NUM];
if (database.yts == NULL) return FALSE;
memset(database.yts, 0, sizeof(struYT) * DATABASE_YT_NUM);
msgBuffer.buf = new char[MAX_DISPLAY_BUFFER_SIZE];
if (msgBuffer.buf != NULL)
{
memset(msgBuffer.buf, 0, sizeof(char) * MAX_DISPLAY_BUFFER_SIZE);
}
channelBuffer.buf = new char[MAX_DISPLAY_BUFFER_SIZE];
if (channelBuffer.buf != NULL)
{
memset(channelBuffer.buf, 0, sizeof(char) * MAX_DISPLAY_BUFFER_SIZE);
}
strcpy(system32.yk_pass, "12345");
system32.yk_keep = 30;
system32.interval_time = 2;
system32.log_enabled = FALSE;
system32.zjd_log_bind_addr = INADDR_ANY;
system32.zjd_log_bind_port = 0;
for (i = 0; i < HARDWARE_PORTS_NUM; i++)
{
snprintf(config.hardware.ports[i].name, MAX_NAME_SIZE, "ttyS%d", i + 100);
config.hardware.ports[i].baud = 9600;
config.hardware.ports[i].data = 8;
config.hardware.ports[i].parity = 0;
config.hardware.ports[i].stop = 0;
config.hardware.ports[i].timeout = 1000; //1s
}
for (i = 0; i < PROCESSES_NUM; i++)
{
snprintf(config.processes[i].name, MAX_NAME_SIZE, "PROC%02d", i);
config.processes[i].softdog = 0;
for (j = 0; j < PROCESS_UNIT_NUM; j++)
{
config.processes[i].units[j] = -1;
}
}
for (i = 0; i < UNIT_NUM; i++)
{
config.units[i].softdog = 0;
}
return TRUE;
}
BOOLEAN ReadSystemCFG(void)
{
FILE *pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_SYSTEM_CONFIG);
pf = fopen(pathName, "rb");
if (pf != NULL)
{
fread(&system32, sizeof(system32), 1, pf);
fclose(pf);
return TRUE;
}
return FALSE;
}
BOOLEAN WriteSystemCFG(void)
{
FILE* pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_SYSTEM_CONFIG);
pf = fopen(pathName, "wb+");
if (pf != NULL)
{
fwrite(&system32, sizeof(system32), 1, pf);
fclose(pf);
return TRUE;
}
return FALSE;
}
BOOLEAN ReadNodeCFG(void)
{
FILE *pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_NODE_CONFIG);
pf = fopen(pathName, "rb");
if (pf != NULL)
{
fread(&nodes, sizeof(nodes), 1, pf);
fclose(pf);
return TRUE;
}
return FALSE;
}
BOOLEAN WriteNodeCFG(void)
{
FILE *pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_NODE_CONFIG);
pf = fopen(pathName, "wb+");
if (pf != NULL)
{
fwrite(&nodes, sizeof(nodes), 1, pf);
fclose(pf);
return TRUE;
}
return FALSE;
}
BOOLEAN ReadHardwareCFG(void)
{
FILE *pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_HARDWARE_CONFIG);
pf = fopen(pathName, "rb");
if (pf != NULL)
{
fread(&config.hardware, sizeof(config.hardware), 1, pf);
fclose(pf);
return TRUE;
}
return FALSE;
}
BOOLEAN WriteHardwareCFG(void)
{
FILE* pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_HARDWARE_CONFIG);
pf = fopen(pathName, "wb+");
if (pf != NULL)
{
fwrite(&config.hardware, sizeof(config.hardware), 1, pf);
fclose(pf);
return TRUE;
}
return FALSE;
}
BOOLEAN ReadProcessCFG(void)
{
FILE *pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_PROCESS_CONFIG);
pf = fopen(pathName, "rb");
if (pf != NULL)
{
fread(&config.processes, sizeof(config.processes), 1, pf);
fclose(pf);
return TRUE;
}
return FALSE;
}
BOOLEAN WriteProcessCFG(void)
{
FILE* pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_PROCESS_CONFIG);
pf = fopen(pathName, "wb+");
if (pf != NULL)
{
fwrite(&config.processes, sizeof(config.processes), 1, pf);
fclose(pf);
return TRUE;
}
return FALSE;
}
BOOLEAN ReadUnitCFG(void)
{
int i, j;
char pathName[512];
char filename[512];
FILE *pf = NULL;
FILE *pfPoint = NULL;
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_UNIT_CONFIG);
pf = fopen(pathName, "rb");
if (pf != NULL)
{
for (i = 0; i < UNIT_NUM; i++)
{
if (feof(pf)) break;
if (fread(&config.units[i], sizeof(config.units[i]), 1, pf) != 1) break;
config.units[i].yxs = NULL;
config.units[i].ycs = NULL;
config.units[i].yms = NULL;
config.units[i].yks = NULL;
config.units[i].yts = NULL;
if (config.units[i].yxcount > 0)
{
config.units[i].yxs = new struUnitYX[config.units[i].yxcount];
if (NULL == config.units[i].yxs) return FALSE;
memset(config.units[i].yxs, 0, sizeof(struUnitYX)*config.units[i].yxcount);
snprintf(filename, sizeof(filename), FILE_UNIT_YX_CONFIG, configpath, i);
pfPoint = fopen(filename, "rb");
if (pfPoint != NULL)
{
fread(config.units[i].yxs, sizeof(struUnitYX)*config.units[i].yxcount, 1, pfPoint);
fclose(pfPoint);
}
else
{
for (j = 0; j < config.units[i].yxcount; j++)
{
config.units[i].yxs[j].order = -1;
config.units[i].yxs[j].qds = 0x80;
}
}
}
if (config.units[i].yccount > 0)
{
config.units[i].ycs = new struUnitYC[config.units[i].yccount];
if (NULL == config.units[i].ycs) return FALSE;
memset(config.units[i].ycs, 0, sizeof(struUnitYC)*config.units[i].yccount);
snprintf(filename, sizeof(filename), FILE_UNIT_YC_CONFIG, configpath, i);
pfPoint = fopen(filename, "rb");
if (pfPoint != NULL)
{
fread(config.units[i].ycs, sizeof(struUnitYC)*config.units[i].yccount, 1, pfPoint);
fclose(pfPoint);
}
else
{
for (j = 0; j < config.units[i].yccount; j++)
{
config.units[i].ycs[j].order = -1;
config.units[i].ycs[j].factor = 1;
config.units[i].ycs[j].qds = 0x80;
}
}
}
if (config.units[i].ymcount > 0)
{
config.units[i].yms = new struUnitYM[config.units[i].ymcount];
if (NULL == config.units[i].yms) return FALSE;
memset(config.units[i].yms, 0,sizeof(struUnitYM)*config.units[i].ymcount);
snprintf(filename, sizeof(filename), FILE_UNIT_YM_CONFIG, configpath, i);
pfPoint = fopen(filename, "rb");
if (pfPoint != NULL)
{
fread(config.units[i].yms, sizeof(struUnitYM)*config.units[i].ymcount, 1, pfPoint);
fclose(pfPoint);
}
else
{
for (j = 0; j < config.units[i].ymcount; j++)
{
config.units[i].yms[j].order = -1;
}
}
}
if (config.units[i].ykcount > 0)
{
config.units[i].yks = new struUnitYK[config.units[i].ykcount];
if (NULL == config.units[i].yks) return FALSE;
memset(config.units[i].yks, 0, sizeof(struUnitYK)*config.units[i].ykcount);
snprintf(filename, sizeof(filename), FILE_UNIT_YK_CONFIG, configpath, i);
pfPoint = fopen(filename, "rb");
if (pfPoint != NULL)
{
fread(config.units[i].yks, sizeof(struUnitYK)*config.units[i].ykcount, 1, pfPoint);
fclose(pfPoint);
}
else
{
for (j = 0; j < config.units[i].ykcount; j++)
{
config.units[i].yks[j].order = -1;
}
}
}
if (config.units[i].ytcount > 0)
{
config.units[i].yts = new struUnitYT[config.units[i].ytcount];
if (NULL == config.units[i].yts) return FALSE;
memset(config.units[i].yts, 0, sizeof(struUnitYT)*config.units[i].ytcount);
snprintf(filename, sizeof(filename), FILE_UNIT_YT_CONFIG, configpath, i);
pfPoint = fopen(filename, "rb");
if (pfPoint != NULL)
{
fread(config.units[i].yts, sizeof(struUnitYT)*config.units[i].ytcount, 1, pfPoint);
fclose(pfPoint);
}
else
{
for (j = 0; j < config.units[i].ytcount; j++)
{
config.units[i].yts[j].order = -1;
}
}
}
}
fclose(pf);
return TRUE;
}
return FALSE;
}
BOOLEAN WriteUnitCFG(void)
{
int i;
char filename[512];
char pathName[512];
FILE *pf = NULL;
FILE *pfPoint = NULL;
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_UNIT_CONFIG);
pf = fopen(pathName, "wb+");
if (pf != NULL)
{
for (i = 0; i < UNIT_NUM; i++)
{
if (fwrite(&config.units[i], sizeof(config.units[i]), 1, pf) != 1) break;
if (config.units[i].yxcount > 0)
{
if (config.units[i].yxs != NULL)
{
snprintf(filename, sizeof(filename), FILE_UNIT_YX_CONFIG, configpath, i);
pfPoint = fopen(filename, "wb+");
if (pfPoint != NULL)
{
fwrite(config.units[i].yxs, sizeof(struUnitYX)*config.units[i].yxcount, 1, pfPoint);
fclose(pfPoint);
}
}
}
if (config.units[i].yccount > 0)
{
if (config.units[i].ycs != NULL)
{
snprintf(filename, sizeof(filename), FILE_UNIT_YC_CONFIG, configpath, i);
pfPoint = fopen(filename, "wb+");
if (pfPoint != NULL)
{
fwrite(config.units[i].ycs, sizeof(struUnitYC)*config.units[i].yccount, 1, pfPoint);
fclose(pfPoint);
}
}
}
if (config.units[i].ymcount > 0)
{
if (config.units[i].yms != NULL)
{
snprintf(filename, sizeof(filename), FILE_UNIT_YM_CONFIG, configpath, i);
pfPoint = fopen(filename, "wb+");
if (pfPoint != NULL)
{
fwrite(config.units[i].yms, sizeof(struUnitYM)*config.units[i].ymcount, 1, pfPoint);
fclose(pfPoint);
}
}
}
if (config.units[i].ykcount > 0)
{
if (config.units[i].yks != NULL)
{
snprintf(filename, sizeof(filename), FILE_UNIT_YK_CONFIG, configpath, i);
pfPoint = fopen(filename, "wb+");
if (pfPoint != NULL)
{
fwrite(config.units[i].yks, sizeof(struUnitYK)*config.units[i].ykcount, 1, pfPoint);
fclose(pfPoint);
}
}
}
if (config.units[i].ytcount > 0)
{
if (config.units[i].yts != NULL)
{
snprintf(filename, sizeof(filename), FILE_UNIT_YT_CONFIG, configpath, i);
pfPoint = fopen(filename, "wb+");
if (pfPoint != NULL)
{
fwrite(config.units[i].yts, sizeof(struUnitYT)*config.units[i].ytcount, 1, pfPoint);
fclose(pfPoint);
}
}
}
}
fclose(pf);
return TRUE;
}
return FALSE;
}
BOOLEAN ReadStaticUnitCFG(void)
{
FILE *pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_UNIT_STATIC);
pf = fopen(pathName, "rb");
if (pf)
{
fread(static_units, sizeof(static_units), 1, pf);
fclose(pf);
return TRUE;
}
return FALSE;
}
BOOLEAN WriteStaticUnitCFG(void)
{
FILE *pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_UNIT_STATIC);
pf = fopen(pathName, "w+");
if (pf != NULL)
{
fwrite(static_units, sizeof(static_units), 1, pf);
fclose(pf);
return TRUE;
}
return FALSE;
}
BOOLEAN ReadDatabaseCFG(void)
{
FILE *pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_DATABASE_CONFIG);
pf = fopen(pathName, "rb");
if (pf != NULL)
{
if (!feof(pf))
{
fread(database.yxs, sizeof(struYX) * DATABASE_YX_NUM, 1, pf);
}
if (!feof(pf))
{
fread(database.ycs, sizeof(struYC) * DATABASE_YC_NUM, 1, pf);
}
if (!feof(pf))
{
fread(database.yms, sizeof(struYM) * DATABASE_YM_NUM, 1, pf);
}
if (!feof(pf))
{
fread(database.yks, sizeof(struYK) * DATABASE_YK_NUM, 1, pf);
}
if (!feof(pf))
{
fread(database.yts, sizeof(struYT) * DATABASE_YT_NUM, 1, pf);
}
fclose(pf);
return TRUE;
}
return FALSE;
}
BOOLEAN WriteDatabaseCFG(void)
{
FILE *pf;
char pathName[512];
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, FILE_DATABASE_CONFIG);
pf = fopen(pathName, "wb+");
if (pf != NULL)
{
fwrite(database.yxs, sizeof(struYX) * DATABASE_YX_NUM, 1, pf);
fwrite(database.ycs, sizeof(struYC) * DATABASE_YC_NUM, 1, pf);
fwrite(database.yms, sizeof(struYM) * DATABASE_YM_NUM, 1, pf);
fwrite(database.yks, sizeof(struYK) * DATABASE_YK_NUM, 1, pf);
fwrite(database.yts, sizeof(struYT) * DATABASE_YT_NUM, 1, pf);
fclose(pf);
return TRUE;
}
return FALSE;
}
#if 0
//此处定义一个map来放置irn和协议的order的关系
typedef std::map<QWORD, int> mapIRN2Order;
BOOLEAN processUartParam(std::string jsonvalue, int ord)
{
Json::Value jsonRoot;
char* pData = (char *)jsonvalue.c_str();
const int rawJsonLength = static_cast<int>(strlen(pData));
std::string err;
Json::CharReaderBuilder builder;
builder["emitUTF8"] = true;
Json::CharReader* reader(builder.newCharReader());
if (!reader->parse(pData, pData + rawJsonLength, &jsonRoot, &err))
{
vLog(LOG_ERROR, "串口参数Json 格式错误!\n");
return FALSE;
}
config.hardware.ports[ord].state = TRUE;
snprintf(config.hardware.ports[ord].name, sizeof(config.hardware.ports[ord].name), "ttyS%d", ord);
config.hardware.ports[ord].baud = 9600;
config.hardware.ports[ord].data = 8;
config.hardware.ports[ord].parity = 0;
config.hardware.ports[ord].stop = 0;
config.hardware.ports[ord].timeout = 1000;
if (jsonRoot["name"].isString())
{
snprintf(config.hardware.ports[ord].name, sizeof(config.hardware.ports[ord].name), "%s", jsonRoot["name"].asCString());
}
if (jsonRoot["baud"].isInt())
{
config.hardware.ports[ord].baud = jsonRoot["baud"].asInt();
}
else if (jsonRoot["baud"].isString())
{
config.hardware.ports[ord].baud = atoi(jsonRoot["baud"].asCString());
}
if (jsonRoot["data"].isInt())
{
config.hardware.ports[ord].data = jsonRoot["data"].asInt();
}
else if (jsonRoot["data"].isString())
{
config.hardware.ports[ord].data = atoi(jsonRoot["data"].asCString());
}
if (jsonRoot["parity"].isInt())
{
config.hardware.ports[ord].parity = jsonRoot["parity"].asInt();
}
else if (jsonRoot["parity"].isString())
{
config.hardware.ports[ord].parity = atoi(jsonRoot["parity"].asCString());
}
if (jsonRoot["stop"].isInt())
{
if (jsonRoot["stop"].asInt() == 1) config.hardware.ports[ord].stop = 0;
else if (jsonRoot["stop"].asInt() == 2) config.hardware.ports[ord].stop = 2;
}
else if (jsonRoot["stop"].isString())
{
if (jsonRoot["stop"].asString() == "1") config.hardware.ports[ord].stop = 0;
else if (jsonRoot["stop"].asString() == "2") config.hardware.ports[ord].stop = 2;
}
if (jsonRoot["timeout"].isInt())
{
config.hardware.ports[ord].timeout = jsonRoot["timeout"].asInt();
}
else if (jsonRoot["timeout"].isString())
{
config.hardware.ports[ord].timeout = atoi(jsonRoot["timeout"].asCString());
}
return TRUE;
}
BOOLEAN processissMqttParam(std::string jsonvalue, const char* client_id, int ord)
{
Json::Value jsonRoot;
char* pData = (char *)jsonvalue.c_str();
const int rawJsonLength = static_cast<int>(strlen(pData));
std::string err;
Json::CharReaderBuilder builder;
builder["emitUTF8"] = true;
Json::CharReader* reader(builder.newCharReader());
if (!reader->parse(pData, pData + rawJsonLength, &jsonRoot, &err))
{
vLog(LOG_ERROR, "软通mqtt协议Json 格式错误!\n");
return FALSE;
}
struISSMQTTOption* issmqttOption = (struISSMQTTOption *)config.processes[ord].option.data;
snprintf(issmqttOption->client_id, MAX_ID_LENGTH, "%s", client_id);
snprintf(issmqttOption->username, sizeof(issmqttOption->username), "%s", "nmu8000");
snprintf(issmqttOption->password, sizeof(issmqttOption->password), "%s", "spi@84805353");
snprintf(issmqttOption->host, sizeof(issmqttOption->host), "%s", "localhost");
//issmqttOption->target_addr = 0x0100007f;
issmqttOption->target_port = MQTT_DEFAULT_PORT;
issmqttOption->connectInterval = 30; //链接等待
issmqttOption->keepAliveInterval = 60; //心跳链接
issmqttOption->connectTimeout = 30; //链接等待超时
issmqttOption->publishInterval = 60; //数据发送间隔
if (jsonRoot["host"].isString())
{
//inet_pton(AF_INET, jsonRoot["host"].asCString(), (struct in_addr*)&issmqttOption->target_addr);
snprintf(issmqttOption->host, sizeof(issmqttOption->host), "%s", jsonRoot["host"].asCString());
}
if (jsonRoot["port"].isInt())
{
issmqttOption->target_port = jsonRoot["port"].asInt();
}
else if (jsonRoot["port"].isString())
{
issmqttOption->target_port = atoi(jsonRoot["port"].asCString());
}
if (jsonRoot["username"].isString())
{
snprintf(issmqttOption->username, sizeof(issmqttOption->username), "%s", jsonRoot["username"].asCString());
}
if (jsonRoot["password"].isString())
{
snprintf(issmqttOption->password, sizeof(issmqttOption->password), "%s", jsonRoot["password"].asCString());
}
#if 0
if (jsonRoot["clientid"].isString())
{
snprintf(issmqttOption->client_id, sizeof(issmqttOption->client_id), "%s", jsonRoot["clientid"].asCString());
}
#endif
if (jsonRoot["pushInterval"].isInt())
{
issmqttOption->publishInterval = jsonRoot["pushInterval"].asInt();
}
else if (jsonRoot["pushInterval"].isString())
{
issmqttOption->publishInterval = atoi(jsonRoot["pushInterval"].asCString());
}
return TRUE;
}
BOOLEAN processLMMqttParam(std::string jsonvalue, int ord)
{
Json::Value jsonRoot;
char* pData = (char *)jsonvalue.c_str();
const int rawJsonLength = static_cast<int>(strlen(pData));
std::string err;
Json::CharReaderBuilder builder;
builder["emitUTF8"] = true;
Json::CharReader* reader(builder.newCharReader());
if (!reader->parse(pData, pData + rawJsonLength, &jsonRoot, &err))
{
vLog(LOG_ERROR, "罗米mqtt协议Json 格式错误!\n");
return FALSE;
}
struLMMQTTOption* lmmqttOption = (struLMMQTTOption *)config.processes[ord].option.data;
snprintf(lmmqttOption->client_id, MAX_ID_LENGTH, "%s", "dianzhong::空港产业城26栋");
snprintf(lmmqttOption->device_id, MAX_ID_LENGTH, "%s", "空港产业城26栋");
snprintf(lmmqttOption->topic, sizeof(lmmqttOption->topic), "%s", "v1/dianzhong/de/#");
snprintf(lmmqttOption->username, sizeof(lmmqttOption->username), "%s", "lmgateway");
snprintf(lmmqttOption->password, sizeof(lmmqttOption->password), "%s", "spi@84805353");
snprintf(lmmqttOption->host, sizeof(lmmqttOption->host), "%s", "localhost");
//lmmqttOption->target_addr = 0x0100007f;
lmmqttOption->target_port = MQTT_DEFAULT_PORT;
lmmqttOption->connectInterval = 30; //链接等待
lmmqttOption->keepAliveInterval = 60; //心跳链接
lmmqttOption->connectTimeout = 30; //链接等待超时
if (jsonRoot["host"].isString())
{
//inet_pton(AF_INET, jsonRoot["host"].asCString(), (struct in_addr*)&lmmqttOption->target_addr);
snprintf(lmmqttOption->host, sizeof(lmmqttOption->host), "%s", jsonRoot["host"].asCString());
}
if (jsonRoot["port"].isInt())
{
lmmqttOption->target_port = jsonRoot["port"].asInt();
}
else if (jsonRoot["port"].isString())
{
lmmqttOption->target_port = atoi(jsonRoot["port"].asCString());
}
if (jsonRoot["username"].isString())
{
snprintf(lmmqttOption->username, sizeof(lmmqttOption->username), "%s", jsonRoot["username"].asCString());
}
if (jsonRoot["password"].isString())
{
snprintf(lmmqttOption->password, sizeof(lmmqttOption->password), "%s", jsonRoot["password"].asCString());
}
if (jsonRoot["clientid"].isString())
{
snprintf(lmmqttOption->client_id, sizeof(lmmqttOption->client_id), "%s", jsonRoot["clientid"].asCString());
}
if (jsonRoot["deviceid"].isString())
{
snprintf(lmmqttOption->device_id, sizeof(lmmqttOption->device_id), "%s", jsonRoot["deviceid"].asCString());
}
if (jsonRoot["topic"].isString())
{
snprintf(lmmqttOption->topic, sizeof(lmmqttOption->topic), "%s", jsonRoot["topic"].asCString());
}
return TRUE;
}
#define LM_TYPE_YX 0
#define LM_TYPE_YC 1
#define LM_TYPE_YM 2
#define LM_TYPE_YK 3
#define LM_TYPE_YT 4
BOOLEAN processLMPointParam(std::string jsonvalue, int uid, int point, int type)
{
Json::Value jsonRoot;
char* pData = (char *)jsonvalue.c_str();
const int rawJsonLength = static_cast<int>(strlen(pData));
std::string err;
Json::CharReaderBuilder builder;
builder["emitUTF8"] = true;
Json::CharReader* reader(builder.newCharReader());
if (!reader->parse(pData, pData + rawJsonLength, &jsonRoot, &err))
{
vLog(LOG_ERROR, "罗米mqtt协议Json 格式错误!\n");
return FALSE;
}
char *description;
switch (type)
{
case LM_TYPE_YX:
description = (char *)config.units[uid].yxs[point].m_param;
break;
case LM_TYPE_YC:
description = (char *)config.units[uid].ycs[point].m_param;
config.units[uid].ycs[point].factor = 100;
config.units[uid].ycs[point].coef = 0.01;
break;
case LM_TYPE_YM:
description = (char *)config.units[uid].yms[point].m_param;
break;
case LM_TYPE_YK:
description = (char *)config.units[uid].yks[point].m_param;
break;
case LM_TYPE_YT:
description = (char *)config.units[uid].yts[point].m_param;
break;
default: break;
}
if (jsonRoot["col1"].isString())
{
snprintf(description, MAX_UNIT_POINT_PARAM_SIZE, "%s", jsonRoot["col1"].asCString());
}
return TRUE;
}
BOOLEAN ReadConfigFromSQLite(BOOLEAN enable_auto_platform, const char* issmqtt_config_pathName, char* codeName)
{
int i;
clock_t start;
double Total_time;
int count = 0;
char query[512];
char pathName[(MAX_PATH<<1)+32];
char szHostCode[128] = {'\0'};
BOOLEAN have_local_debug = FALSE; //是否配置了本地调试协议
short issmqtt_pid = -1; //软通mqtt协议ID
short config_process_count = 0; //配置的协议/链路数量
short config_unit_count = 0; //配置的单元数量
short unit_link_proto[UNIT_NUM]; //单元所链接的协议序号
mapIRN2Order irn2PID;
mapIRN2Order irn2UID;
memset(static_units, 0, sizeof(static_units));
snprintf(pathName, sizeof(pathName), "%s/%s", configpath, configfile);
try
{
SQLiteDatabase* pDatabase = new SQLiteDatabase(pathName, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
pDatabase->MoveDatabaseToMemory();
SQLiteStatement* pStmt = new SQLiteStatement(pDatabase);
//获取配置信息
//1、获取工程信息
//获取本机节点号通过节点号获取Node信息。
char szHostName[32] = "";
gethostname(szHostName, sizeof(szHostName));
memset(szHostCode, '\0', sizeof(szHostCode));
//2、获取节点信息
start = clock();
pStmt->BeginTransaction();
snprintf(query, sizeof(query), "SELECT cn.NODENO, cn.TCI_TYPE, cn.TARGET_ADDR, cn.TARGET_PORT, co.NAME, co.IRN, cn.CODE FROM CMG_NODE cn JOIN CMG_OBJECT co ON co.IRN = cn.IRN ;");
pStmt->Sql(query);
count = 0;
while (pStmt->FetchRow())
{
nodes.m_node[count].m_netnode_no = pStmt->GetColumnInt(0);
nodes.m_node[count].m_tcitype = pStmt->GetColumnInt(1) ? pStmt->GetColumnInt(1) : 1;
nodes.m_node[count].m_target_addr = pStmt->GetColumnInt(2);
nodes.m_node[count].m_target_port = pStmt->GetColumnInt(3);
snprintf(nodes.m_node[count].m_machine_name, sizeof(nodes.m_node[count].m_machine_name), "%s", szHostName);
nodes.m_node[count].irn = pStmt->GetColumnInt64(5);
snprintf(szHostCode, sizeof(szHostCode), "%s", pStmt->GetColumnCString(6));
snprintf(codeName, sizeof(codeName), "%s", pStmt->GetColumnCString(6));
vLog(LOG_DEBUG, "nodes.m_node[%d].m_machine_name is: %s\n", count, nodes.m_node[count].m_machine_name);
count++;
}
pStmt->FreeQuery();
pStmt->CommitTransaction();
if (count <= 0)
{
delete pStmt;
delete pDatabase;
return FALSE;
}
count = 0;
Total_time = (double)(clock() - start) / CLOCKS_PER_SEC; //单位换算成秒
vLog(LOG_DEBUG, "获取节点配置 use: %f seconds\n", Total_time);
//4、获取协议配置
start = clock();
count = 0;
int uart_order = 0;
irn2PID.clear();
pStmt->BeginTransaction();
pStmt->Sql("SELECT co.NAME, cl.STATE, cl.ACCEPT_TIME, cl.PROTOCOL, cl.TIME_GAP, cl.POLL_GAP, cl.OPTION, cl.IRN FROM CMG_LINEUNIT cl JOIN CMG_OBJECT co ON cl.IRN = co.IRN");
while (pStmt->FetchRow())
{
snprintf(config.processes[count].name, sizeof(config.processes[count].name), "%s", pStmt->GetColumnCString(0));
config.processes[count].state = pStmt->GetColumnInt(1);
config.processes[count].time_accept = pStmt->GetColumnInt(2);
config.processes[count].proto = pStmt->GetColumnInt(3);
config.processes[count].time_gap = pStmt->GetColumnInt(4);
config.processes[count].poll_gap = pStmt->GetColumnInt(5);
std::string option = pStmt->GetColumnString(6); //根据协议来解析
switch (config.processes[count].proto)
{
case PROTOCOL_HOST_IEC104:
case PROTOCOL_HOST_MODBUS_TCP:
case PROTOCOL_HOST_MODBUS_RTU_TCP:
case PROTOCOL_RTU_STATE:
config.processes[count].mode = PROCESS_MODE_MASTER;
break;
case PROTOCOL_LOCAL_DEBUG:
have_local_debug = TRUE;
config.processes[count].mode = PROCESS_MODE_MASTER;
break;
case PROTOCOL_HOST_NSA:
case PROTOCOL_HOST_MODBUS_RTU:
case PROTOCOL_HOST_MODBUS_RTU_NCY:
case PROTOCOL_HOST_MODBUS_RTU_LIYEZG:
case PROTOCOL_HOST_MODBUS_ASCII:
case PROTOCOL_SUB_MODBUS_RTU:
case PROTOCOL_HOST_DLT645V2007:
processUartParam(option, uart_order);
config.processes[count].mode = PROCESS_MODE_MASTER;
config.processes[count].order = uart_order++;
break;
case PROTOCOL_AGC:
case PROTOCOL_AVC:
config.processes[count].mode = PROCESS_MODE_DUPLEX;
break;
case PROTOCOL_SUB_IEC104:
case PROTOCOL_SUB_GDW104:
case PROTOCOL_SUB_XT9712:
case PROTOCOL_SUB_MODBUS_TCP:
case PROTOCOL_DLT_1867:
case PROTOCOL_HW_MQTT:
config.processes[count].mode = PROCESS_MODE_SLAVE;
break;
case PROTOCOL_ISS_MQTT:
issmqtt_pid = count;
processissMqttParam(option, szHostCode, count);
config.processes[count].mode = PROCESS_MODE_SLAVE;
break;
case PROTOCOL_LM_MQTT:
processLMMqttParam(option, count);
config.processes[count].mode = PROCESS_MODE_MASTER;
break;
case PROTOCOL_BF_FTP:
processissMqttParam(option, szHostCode, count);
config.processes[count].mode = PROCESS_MODE_SLAVE;
break;
default: break;
}
QWORD irn = pStmt->GetColumnInt64(7);
config.processes[count].irn = irn;
if (irn2PID.find(irn) == irn2PID.end())
{
irn2PID.insert(std::map<QWORD, int>::value_type(irn, count));
}
count++;
}
config_process_count = count;
pStmt->FreeQuery();
pStmt->CommitTransaction();
count = 0;
Total_time = (double)(clock() - start) / CLOCKS_PER_SEC; //单位换算成秒
vLog(LOG_DEBUG, "获取协议配置 use: %f seconds\n", Total_time);
//5、获取单元配置
start = clock();
count = 0;
irn2UID.clear();
pStmt->BeginTransaction();
pStmt->Sql("SELECT co.NAME, cu.MODEL, cu.MANUFACTURERID, cu.DEVICEID, cu.STATE, cu.UTYPE, cu.ADDRESS, cu.YXCOUNT, cu.YCCOUNT, cu.YMCOUNT, cu.YKCOUNT, cu.YTCOUNT, co.PARENT, co.IRN FROM CMG_UNIT cu JOIN CMG_OBJECT co ON cu.IRN = co.IRN;");
while (pStmt->FetchRow())
{
snprintf(static_units[count].name, sizeof(static_units[count].name), "%s", pStmt->GetColumnCString(0));
snprintf(static_units[count].model, sizeof(static_units[count].model), "%s", pStmt->GetColumnCString(1));
snprintf(static_units[count].manufacturerId, sizeof(static_units[count].manufacturerId), "%s", pStmt->GetColumnCString(2));
snprintf(static_units[count].deviceId, sizeof(static_units[count].deviceId), "%s", pStmt->GetColumnCString(3));
config.units[count].state = pStmt->GetColumnInt(4);
if (pStmt->GetColumnType(5) == 5)
{
config.units[count].type = 1;
}
else
{
config.units[count].type = pStmt->GetColumnInt(5);
}
std::string address = pStmt->GetColumnString(6);
config.units[count].yxs = NULL;
config.units[count].ycs = NULL;
config.units[count].yms = NULL;
config.units[count].yks = NULL;
config.units[count].yts = NULL;
config.units[count].yxcount = pStmt->GetColumnInt(7);
config.units[count].yccount = pStmt->GetColumnInt(8);
config.units[count].ymcount = pStmt->GetColumnInt(9);
config.units[count].ykcount = pStmt->GetColumnInt(10);
config.units[count].ytcount = pStmt->GetColumnInt(11);
QWORD parentIRN = pStmt->GetColumnInt64(12);
QWORD IRN = pStmt->GetColumnInt64(13);
config.units[count].irn = IRN;
if (irn2UID.find(IRN) == irn2UID.end())
{
irn2UID.insert(std::map<QWORD, int>::value_type(IRN, count));
}
//根据父IRN确定该设备所链接的协议
int pid = irn2PID[parentIRN];
if (pid >= 0 && pid < PROCESSES_NUM)
{
//此处得到该单元所链接的协议。
//根据协议,选择默认的单元配置
#if 0
case PROTOCOL_HOST_MODBUS_RTU_NCY:
case PROTOCOL_HOST_MODBUS_RTU_LIYEZG:
std::ifstream ifile;
char pathName[MAX_PATH];
snprintf(pathName, sizeof(pathName), "%s../etc/devices.json", configpath);
fprintf(stderr, "pathName is: %s\n", pathName);
ifile.open(pathName);
//2.创建json读工厂对象
Json::CharReaderBuilder ReaderBuilder;
ReaderBuilder["emitUTF8"] = true;//utf8支持不加这句utf8的中文字符会编程\uxxx
//3.创建json对象等会要返回这个对象
Json::Value root;
//4.把文件转变为json对象要用到上面的三个变量,数据写入root
std::string strerr;
bool ok = Json::parseFromStream(ReaderBuilder, ifile, &root, &strerr);
if (!ok)
{
vLog(LOG_DEBUG, "json解析错误<%s>\n", strerr.c_str());
}
ifile.close();
switch (config.processes[pid].proto)
{
case PROTOCOL_HOST_MODBUS_RTU_NCY:
break;
case PROTOCOL_HOST_MODBUS_RTU_LIYEZG:
break;
default:
break;
}
#endif
for (i = 0; i < PROCESS_UNIT_NUM; i++)
{
if (config.processes[pid].units[i] < 0)
{
config.processes[pid].units[i] = count;
break;
}
}
}
unit_link_proto[count] = config.processes[pid].proto;
BYTE addrType = ADDR_TYPE_NORMAL; //根据协议设定单元地址类型
switch (config.processes[pid].proto)
{
case PROTOCOL_HOST_IEC104:
case PROTOCOL_SUB_IEC104:
case PROTOCOL_SUB_GDW104:
case PROTOCOL_SUB_XT9712:
addrType = ADDR_TYPE_IPV4_FACNO;
break;
case PROTOCOL_HOST_NSA:
case PROTOCOL_HOST_MODBUS_RTU:
case PROTOCOL_HOST_MODBUS_ASCII:
case PROTOCOL_HOST_MODBUS_RTU_NCY:
case PROTOCOL_HOST_MODBUS_RTU_LIYEZG:
addrType = ADDR_TYPE_NORMAL;
break;
case PROTOCOL_HOST_MODBUS_TCP:
case PROTOCOL_HOST_MODBUS_RTU_TCP:
case PROTOCOL_DLT_1867:
case PROTOCOL_LOCAL_DEBUG:
case PROTOCOL_HW_MQTT:
case PROTOCOL_ISS_MQTT:
case PROTOCOL_LM_MQTT:
addrType = ADDR_TYPE_IPV4;
break;
case PROTOCOL_HOST_DLT645V2007:
addrType = ADDR_TYPE_HEX;
break;
default:
break;
}
if (addrType == ADDR_TYPE_HEX)
{
StringToHex(address.c_str(), config.units[count].addr);
}
else if (addrType == ADDR_TYPE_IPV4)
{
DWORD addr;
inet_pton(AF_INET, address.c_str(), (struct in_addr*)&addr);
memcpy(config.units[count].addr, &addr, sizeof(addr));
}
else if (addrType == ADDR_TYPE_IPV4_FACNO)
{
char* pData = (char*)address.c_str();
char* pBuf = strchr(pData, ':');
if (pBuf != NULL)
{
*pBuf = '\0'; pBuf++;
DWORD addr;
inet_pton(AF_INET, pData, (struct in_addr*)&addr);
memcpy(config.units[count].addr, &addr, sizeof(addr));
addr = (DWORD)atoi(pBuf);
memcpy(&config.units[count].addr[4], &addr, sizeof(addr));
}
}
else
{
DWORD addr = (DWORD)atoi(address.c_str());
memcpy(config.units[count].addr, &addr, sizeof(addr));
}
count++;
}
config_unit_count = count;
pStmt->FreeQuery();
pStmt->CommitTransaction();
Total_time = (double)(clock() - start) / CLOCKS_PER_SEC; //单位换算成秒
vLog(LOG_DEBUG, "获取单元配置 use: %f seconds\n", Total_time);
start = clock();
count = 0;
int total_yx = 0;
int total_yc = 0;
int total_ym = 0;
int total_yk = 0;
int total_yt = 0;
//pStmt->BeginTransaction();
for (std::map<QWORD, int>::iterator it = irn2UID.begin(); it != irn2UID.end(); it++)
{ //此处先获取遥信、遥测等测点数量来初始化。
pStmt->Sql("SELECT COUNT(*) FROM CMG_ANALOG ca join CMG_OBJECT co ON ca.IRN = co.IRN AND co.PARENT = @IRN;");
pStmt->BindInt64(1, it->first);
while (pStmt->FetchRow())
{
config.units[it->second].yccount = pStmt->GetColumnInt(0);
}
pStmt->ExecuteAndFree();
pStmt->Sql("SELECT COUNT(*) FROM CMG_ACCUMULATOR ca join CMG_OBJECT co ON ca.IRN = co.IRN AND co.PARENT = @IRN;");
pStmt->BindInt64(1, it->first);
while (pStmt->FetchRow())
{
config.units[it->second].ymcount = pStmt->GetColumnInt(0);
}
pStmt->ExecuteAndFree();
pStmt->Sql("SELECT COUNT(*) FROM CMG_CONTROL cc join CMG_OBJECT co ON cc.IRN = co.IRN AND co.PARENT = @IRN;");
pStmt->BindInt64(1, it->first);
while (pStmt->FetchRow())
{
config.units[it->second].ykcount = pStmt->GetColumnInt(0);
}
pStmt->ExecuteAndFree();
pStmt->Sql("SELECT COUNT(*) FROM CMG_DISCRETE cd join CMG_OBJECT co ON cd.IRN = co.IRN AND co.PARENT = @IRN;");
pStmt->BindInt64(1, it->first);
while (pStmt->FetchRow())
{
config.units[it->second].yxcount = pStmt->GetColumnInt(0);
}
pStmt->ExecuteAndFree();
pStmt->Sql("SELECT COUNT(*) FROM CMG_SETPOINT cs join CMG_OBJECT co ON cs.IRN = co.IRN AND co.PARENT = @IRN;");
pStmt->BindInt64(1, it->first);
while (pStmt->FetchRow())
{
config.units[it->second].ytcount = pStmt->GetColumnInt(0);
}
pStmt->ExecuteAndFree();
//此处想增加一些读取物模型的代码
//获取测点信息
if (config.units[it->second].yccount > 0)
{
pStmt->Sql("SELECT co.IRN, co.NAME, ca.PTORDER, ca.FACTOR, ca.CHANGEPOS, ca.PARAMETER, ca.COEF, ca.BASE FROM CMG_ANALOG ca JOIN CMG_OBJECT co ON ca.IRN = co.IRN AND co.PARENT = @parent ;");
config.units[it->second].ycs = new struUnitYC[config.units[it->second].yccount];
if (NULL != config.units[it->second].ycs)
{
memset(config.units[it->second].ycs, 0, sizeof(struUnitYC) * config.units[it->second].yccount);
pStmt->BindInt64(1, it->first);
count = 0;
std::vector<QLONG> irns;
irns.clear();
char filename[512];
snprintf(filename, sizeof(filename), FILE_UNIT_YC_STATIC, configpath, it->second);
FILE *pf = fopen(filename, "wb+");
while (pStmt->FetchRow())
{
irns.push_back(pStmt->GetColumnInt64(0));
config.units[it->second].ycs[count].irn = pStmt->GetColumnInt64(0);
if (pf)
{
fwrite(pStmt->GetColumnCString(1), (MAX_NAME_SIZE << 2), 1, pf);
}
//config.units[it->second].ycs[count].order = pStmt->GetColumnInt(2);
config.units[it->second].ycs[count].order = total_yc++;
config.units[it->second].ycs[count].factor = pStmt->GetColumnInt(3);
config.units[it->second].ycs[count].change_pos = pStmt->GetColumnInt(4);
std::string parameter = pStmt->GetColumnString(5);
config.units[it->second].ycs[count].coef = (float)pStmt->GetColumnDouble(6);
config.units[it->second].ycs[count].base = (float)pStmt->GetColumnDouble(7);
if (config.units[it->second].type == 1)
{
database.ycs[config.units[it->second].ycs[count].order].coef = config.units[it->second].ycs[count].coef;
database.ycs[config.units[it->second].ycs[count].order].base = config.units[it->second].ycs[count].base;
}
switch (unit_link_proto[it->second])
{
case PROTOCOL_HOST_IEC104:
case PROTOCOL_SUB_IEC104:
case PROTOCOL_HOST_MODBUS_TCP:
case PROTOCOL_SUB_MODBUS_TCP:
case PROTOCOL_HOST_MODBUS_RTU_TCP:
case PROTOCOL_RTU_STATE:
case PROTOCOL_LOCAL_DEBUG:
case PROTOCOL_SUB_XT9712:
case PROTOCOL_HOST_NSA:
case PROTOCOL_HOST_MODBUS_RTU:
case PROTOCOL_HOST_MODBUS_RTU_NCY:
case PROTOCOL_HOST_MODBUS_RTU_LIYEZG:
case PROTOCOL_HOST_MODBUS_ASCII:
case PROTOCOL_SUB_MODBUS_RTU:
case PROTOCOL_HOST_DLT645V2007:
case PROTOCOL_AGC:
case PROTOCOL_AVC:
case PROTOCOL_DLT_1867:
case PROTOCOL_SUB_GDW104:
case PROTOCOL_HW_MQTT:
case PROTOCOL_ISS_MQTT:
break;
case PROTOCOL_LM_MQTT:
processLMPointParam(parameter, it->second, count, LM_TYPE_YC);
config.processes[count].mode = PROCESS_MODE_MASTER;
break;
default: break;
}
count++;
}
pStmt->ExecuteAndFree();
if (pf) fclose(pf);
}
}
if (config.units[it->second].ymcount > 0)
{
pStmt->Sql("SELECT co.IRN, co.NAME, ca.PTORDER, ca.PARAMETER, ca.COEF, ca.BASE FROM CMG_ACCUMULATOR ca JOIN CMG_OBJECT co ON ca.IRN = co.IRN and co.PARENT = @parent ;");
config.units[it->second].yms = new struUnitYM[config.units[it->second].ymcount];
if (NULL != config.units[it->second].yms)
{
memset(config.units[it->second].yms, 0, sizeof(struUnitYM) * config.units[it->second].ymcount);
pStmt->BindInt64(1, it->first);
count = 0;
std::vector<QLONG> irns;
irns.clear();
char filename[512];
snprintf(filename, sizeof(filename), FILE_UNIT_YM_STATIC, configpath, it->second);
FILE *pf = fopen(filename, "wb+");
while (pStmt->FetchRow())
{
irns.push_back(pStmt->GetColumnInt64(0));
config.units[it->second].yms[count].irn = pStmt->GetColumnInt64(0);
if (pf)
{
fwrite(pStmt->GetColumnCString(1), (MAX_NAME_SIZE << 2), 1, pf);
}
//config.units[it->second].yms[count].order = pStmt->GetColumnInt(2);
config.units[it->second].yms[count].order = total_ym++;
std::string parameter = pStmt->GetColumnString(3);
config.units[it->second].yms[count].coef = (float)pStmt->GetColumnDouble(4);
config.units[it->second].yms[count].base = (float)pStmt->GetColumnDouble(5);
if (config.units[it->second].type == 1)
{
database.yms[config.units[it->second].yms[count].order].coef = config.units[it->second].yms[count].coef;
database.yms[config.units[it->second].yms[count].order].base = config.units[it->second].yms[count].base;
}
count++;
}
pStmt->ExecuteAndFree();
if (pf) fclose(pf);
}
}
if (config.units[it->second].ykcount > 0)
{
pStmt->Sql("SELECT co.IRN, co.NAME, cc.PTORDER, cc.PARAMETER FROM CMG_CONTROL cc JOIN CMG_OBJECT co ON cc.IRN = co.IRN and co.PARENT = @parent ;");
config.units[it->second].yks = new struUnitYK[config.units[it->second].ykcount];
if (NULL != config.units[it->second].yks)
{
memset(config.units[it->second].yks, 0, sizeof(struUnitYK) * config.units[it->second].ykcount);
pStmt->BindInt64(1, it->first);
count = 0;
std::vector<QLONG> irns;
irns.clear();
char filename[512];
snprintf(filename, sizeof(filename), FILE_UNIT_YK_STATIC, configpath, it->second);
FILE *pf = fopen(filename, "wb+");
while (pStmt->FetchRow())
{
irns.push_back(pStmt->GetColumnInt64(0));
config.units[it->second].yks[count].irn = pStmt->GetColumnInt64(0);
if (pf)
{
fwrite(pStmt->GetColumnCString(1), (MAX_NAME_SIZE << 2), 1, pf);
}
//config.units[it->second].yks[count].order = pStmt->GetColumnInt(2);
config.units[it->second].yks[count].order = total_yk++;
std::string parameter = pStmt->GetColumnString(3);
count++;
}
pStmt->ExecuteAndFree();
if (pf) fclose(pf);
}
}
if (config.units[it->second].ytcount > 0)
{
pStmt->Sql("SELECT co.IRN, co.NAME, cs.PTORDER, cs.PARAMETER FROM CMG_SETPOINT cs JOIN CMG_OBJECT co ON cs.IRN = co.IRN and co.PARENT = @parent ;");
config.units[it->second].yts = new struUnitYT[config.units[it->second].ytcount];
if (NULL != config.units[it->second].yts)
{
memset(config.units[it->second].yts, 0, sizeof(struUnitYT) * config.units[it->second].ytcount);
pStmt->BindInt64(1, it->first);
count = 0;
std::vector<QLONG> irns;
irns.clear();
char filename[512];
snprintf(filename, sizeof(filename), FILE_UNIT_YT_STATIC, configpath, it->second);
FILE *pf = fopen(filename, "wb+");
while (pStmt->FetchRow())
{
irns.push_back(pStmt->GetColumnInt64(0));
config.units[it->second].yts[count].irn = pStmt->GetColumnInt64(0);
if (pf)
{
fwrite(pStmt->GetColumnCString(1), (MAX_NAME_SIZE << 2), 1, pf);
}
//config.units[it->second].yts[count].order = pStmt->GetColumnInt(2);
config.units[it->second].yts[count].order = total_yt++;
std::string parameter = pStmt->GetColumnString(3);
count++;
}
pStmt->ExecuteAndFree();
if (pf) fclose(pf);
}
}
if (config.units[it->second].yxcount > 0)
{
pStmt->Sql("SELECT co.IRN, co.NAME, cd.PTORDER, cd.PARAMETER FROM CMG_DISCRETE cd JOIN CMG_OBJECT co ON cd.IRN = co.IRN and co.PARENT = @parent ;");
config.units[it->second].yxs = new struUnitYX[config.units[it->second].yxcount];
if (NULL != config.units[it->second].yxs)
{
memset(config.units[it->second].yxs, 0, sizeof(struUnitYX) * config.units[it->second].yxcount);
pStmt->BindInt64(1, it->first);
count = 0;
std::vector<QLONG> irns;
irns.clear();
char filename[512];
snprintf(filename, sizeof(filename), FILE_UNIT_YX_STATIC, configpath, it->second);
FILE *pf = fopen(filename, "wb+");
while (pStmt->FetchRow())
{
irns.push_back(pStmt->GetColumnInt64(0));
config.units[it->second].yxs[count].irn = pStmt->GetColumnInt64(0);
if (pf)
{
fwrite(pStmt->GetColumnCString(1), (MAX_NAME_SIZE << 2), 1, pf);
}
//config.units[it->second].yxs[count].order = pStmt->GetColumnInt(2);
config.units[it->second].yxs[count].order = total_yx++;
database.yxs[config.units[it->second].yxs[count].order].auto_reset = 0;
std::string parameter = pStmt->GetColumnString(3);
count++;
}
pStmt->ExecuteAndFree();
if (pf) fclose(pf);
}
}
}
Total_time = (double)(clock() - start) / CLOCKS_PER_SEC; //单位换算成秒
vLog(LOG_DEBUG, "获取测点名称 use: %f seconds\n", Total_time);
delete pStmt;
delete pDatabase;
}
catch (SQLiteException& exception)
{
vLog(LOG_ERROR, "Exception Occured SQLite result code: %d,%s\n", exception.GetSqliteResultCode(), exception.GetErrorDescription().c_str());
return FALSE;
}
//判断是否配置了本地调试协议
int local_debug_pid = (PROCESSES_NUM - 1); //config_process_count;
if (!have_local_debug)
{ //没有配置本地协议
snprintf(config.processes[local_debug_pid].name, sizeof(config.processes[local_debug_pid].name), "%s", "本地调试");
config.processes[local_debug_pid].state = TRUE;
config.processes[local_debug_pid].time_accept = FALSE;
config.processes[local_debug_pid].proto = PROTOCOL_LOCAL_DEBUG;
config.processes[local_debug_pid].mode = PROCESS_MODE_MASTER;
config.processes[local_debug_pid].time_gap = 300;
config.processes[local_debug_pid].poll_gap = 5;
config.processes[local_debug_pid].order = 0;
config.processes[local_debug_pid].units[0] = -1;
config.processes[local_debug_pid].option.network.ignored_source = TRUE;
config.processes[local_debug_pid].option.network.socket_type = SOCK_STREAM;
config.processes[local_debug_pid].option.network.bind_port = 9001;
config.processes[local_debug_pid].option.network.bind_addr = INADDR_ANY;
config.processes[local_debug_pid].option.network.target_port = 0;
config.processes[local_debug_pid].option.network.target_addr = INADDR_ANY;
config_process_count++;
}
//判断本地调试协议是否链接了单元
if (config.processes[local_debug_pid].units[0] == -1)
{
int local_debug_uid = (UNIT_NUM - 1);//config_unit_count;
config.units[local_debug_uid].state = TRUE;
config.units[local_debug_uid].type = 1;
config.units[local_debug_uid].addr[0] = 0;
memset(config.units[local_debug_uid].m_param, 0, sizeof(config.units[local_debug_uid].m_param));
config.units[local_debug_uid].yxcount = 0;
config.units[local_debug_uid].yccount = 0;
config.units[local_debug_uid].ymcount = 0;
config.units[local_debug_uid].ykcount = 0;
config.units[local_debug_uid].ytcount = 0;
config.units[local_debug_uid].softdog = 0;
config.units[local_debug_uid].yxbwload = 0;
config.units[local_debug_uid].soeload = 0;
config.units[local_debug_uid].ycbwload = 0;
config.units[local_debug_uid].value = 0;
config.units[local_debug_uid].yxs = NULL;
config.units[local_debug_uid].ycs = NULL;
config.units[local_debug_uid].yms = NULL;
config.units[local_debug_uid].yks = NULL;
config.units[local_debug_uid].yts = NULL;
snprintf(static_units[local_debug_uid].name, sizeof(static_units[local_debug_uid].name), "%s", "本地调试");
snprintf(static_units[local_debug_uid].model, sizeof(static_units[local_debug_uid].model), "%s", "本地调试");
snprintf(static_units[local_debug_uid].manufacturerId, sizeof(static_units[local_debug_uid].manufacturerId), "%s", "iSoftStone");
snprintf(static_units[local_debug_uid].deviceId, sizeof(static_units[local_debug_uid].deviceId), "%s", "");
config.processes[local_debug_pid].units[0] = local_debug_uid;
config_unit_count++;
}
if (enable_auto_platform)
{
if (issmqtt_pid < 0)
{
issmqtt_pid = config_process_count;
snprintf(config.processes[issmqtt_pid].name, sizeof(config.processes[issmqtt_pid].name), "%s", "软通USP平台MQTT");
config.processes[issmqtt_pid].state = TRUE;
config.processes[issmqtt_pid].time_accept = FALSE;
config.processes[issmqtt_pid].proto = PROTOCOL_ISS_MQTT;
config.processes[issmqtt_pid].mode = PROCESS_MODE_SLAVE;
config.processes[issmqtt_pid].time_gap = 300;
config.processes[issmqtt_pid].poll_gap = 5;
config.processes[issmqtt_pid].order = 0;
config.processes[issmqtt_pid].units[0] = -1;
struISSMQTTOption* issmqttOption = (struISSMQTTOption *)config.processes[issmqtt_pid].option.data;
//默认配置
snprintf(issmqttOption->client_id, MAX_ID_LENGTH, "%s", szHostCode);
snprintf(issmqttOption->username, sizeof(issmqttOption->username), "%s", "nmu8000");
snprintf(issmqttOption->password, sizeof(issmqttOption->password), "%s", "spi@84805353");
snprintf(issmqttOption->host, sizeof(issmqttOption->host), "%s", "192.168.109.177");
snprintf(issmqttOption->topic_version, sizeof(issmqttOption->topic_version), "%s", "v100");
issmqttOption->target_port = MQTT_DEFAULT_PORT;
issmqttOption->connectInterval = 30; //链接等待
issmqttOption->keepAliveInterval = 60; //心跳链接
issmqttOption->connectTimeout = 30; //链接等待超时
issmqttOption->publishInterval = 60; //数据发送间隔
//读取配置文件内容
std::ifstream ifs;
Json::Value jsonRoot;
Json::Reader jsonReader;
ifs.open(issmqtt_config_pathName);
if (ifs.is_open())
{
if (jsonReader.parse(ifs, jsonRoot, false))
{
if (jsonRoot["port"].isInt())
{
issmqttOption->target_port = jsonRoot["port"].asInt();
}
if (jsonRoot["host"].isString())
{
snprintf(issmqttOption->host, sizeof(issmqttOption->host), "%s", jsonRoot["host"].asCString());
}
if (jsonRoot["username"].isString())
{
snprintf(issmqttOption->username, sizeof(issmqttOption->username), "%s", jsonRoot["username"].asCString());
}
if (jsonRoot["password"].isString())
{
snprintf(issmqttOption->password, sizeof(issmqttOption->password), "%s", jsonRoot["password"].asCString());
}
if (jsonRoot["topic_version"].isString())
{
snprintf(issmqttOption->topic_version, sizeof(issmqttOption->topic_version), "%s", jsonRoot["topic_version"].asCString());
}
}
else
{
fprintf(stderr, "configure file format is error.\r\n");
}
ifs.close();
}
config_process_count++;
}
if (issmqtt_pid >= 0 && config.processes[issmqtt_pid].units[0] == -1)
{ //配置了软通mqtt协议
int issmqtt_uid = config_unit_count;
config.units[issmqtt_uid].state = TRUE;
config.units[issmqtt_uid].type = 1;
config.units[issmqtt_uid].addr[0] = 0;
memset(config.units[issmqtt_uid].m_param, 0, sizeof(config.units[issmqtt_uid].m_param));
config.units[issmqtt_uid].yxcount = 0;
config.units[issmqtt_uid].yccount = 0;
config.units[issmqtt_uid].ymcount = 0;
config.units[issmqtt_uid].ykcount = 0;
config.units[issmqtt_uid].ytcount = 0;
config.units[issmqtt_uid].softdog = 0;
config.units[issmqtt_uid].yxbwload = 0;
config.units[issmqtt_uid].soeload = 0;
config.units[issmqtt_uid].ycbwload = 0;
config.units[issmqtt_uid].value = 0;
config.units[issmqtt_uid].yxs = NULL;
config.units[issmqtt_uid].ycs = NULL;
config.units[issmqtt_uid].yms = NULL;
config.units[issmqtt_uid].yks = NULL;
config.units[issmqtt_uid].yts = NULL;
snprintf(static_units[issmqtt_uid].name, sizeof(static_units[issmqtt_uid].name), "%s", "本地USP平台");
snprintf(static_units[issmqtt_uid].model, sizeof(static_units[issmqtt_uid].model), "%s", "本地USP平台");
snprintf(static_units[issmqtt_uid].manufacturerId, sizeof(static_units[issmqtt_uid].manufacturerId), "%s", "iSoftStone");
snprintf(static_units[issmqtt_uid].deviceId, sizeof(static_units[issmqtt_uid].deviceId), "%s", "");
config.processes[issmqtt_pid].units[0] = issmqtt_uid;
config.units[issmqtt_uid].yxs = new struUnitYX[UNIT_YX_MAX];
memset(config.units[issmqtt_uid].yxs, 0, sizeof(struUnitYX) * UNIT_YX_MAX);
config.units[issmqtt_uid].ycs = new struUnitYC[UNIT_YC_MAX];
memset(config.units[issmqtt_uid].ycs, 0, sizeof(struUnitYC) * UNIT_YC_MAX);
config.units[issmqtt_uid].yms = new struUnitYM[UNIT_YM_MAX];
memset(config.units[issmqtt_uid].yms, 0, sizeof(struUnitYM) * UNIT_YM_MAX);
config.units[issmqtt_uid].yks = new struUnitYK[UNIT_YK_MAX];
memset(config.units[issmqtt_uid].yks, 0, sizeof(struUnitYK) * UNIT_YK_MAX);
config.units[issmqtt_uid].yts = new struUnitYT[UNIT_YT_MAX];
memset(config.units[issmqtt_uid].yts, 0, sizeof(struUnitYT) * UNIT_YT_MAX);
//将其他单元数据挂载在此单元上
for (i = 0; i < UNIT_NUM; i++)
{
if (config.units[i].state == TRUE && i != issmqtt_uid)
{
if (config.units[i].yxcount > 0)
{
if (config.units[issmqtt_uid].yxcount + config.units[i].yxcount < UNIT_YX_MAX)
{
memcpy(&config.units[issmqtt_uid].yxs[config.units[issmqtt_uid].yxcount], config.units[i].yxs, sizeof(struUnitYX)*config.units[i].yxcount);
config.units[issmqtt_uid].yxcount += config.units[i].yxcount;
}
}
if (config.units[i].yccount > 0)
{
if (config.units[issmqtt_uid].yccount + config.units[i].yccount < UNIT_YC_MAX)
{
memcpy(&config.units[issmqtt_uid].ycs[config.units[issmqtt_uid].yccount], config.units[i].ycs, sizeof(struUnitYC)*config.units[i].yccount);
config.units[issmqtt_uid].yccount += config.units[i].yccount;
}
}
if (config.units[i].ymcount > 0)
{
if (config.units[issmqtt_uid].ymcount + config.units[i].ymcount < UNIT_YM_MAX)
{
memcpy(&config.units[issmqtt_uid].yms[config.units[issmqtt_uid].ymcount], config.units[i].yms, sizeof(struUnitYM)*config.units[i].ymcount);
config.units[issmqtt_uid].ymcount += config.units[i].ymcount;
}
}
if (config.units[i].ykcount > 0)
{
if (config.units[issmqtt_uid].ykcount + config.units[i].ykcount < UNIT_YK_MAX)
{
memcpy(&config.units[issmqtt_uid].yks[config.units[issmqtt_uid].ykcount], config.units[i].yks, sizeof(struUnitYK)*config.units[i].ykcount);
config.units[issmqtt_uid].ykcount += config.units[i].ykcount;
}
}
if (config.units[i].ytcount > 0)
{
if (config.units[issmqtt_uid].ytcount + config.units[i].ytcount < UNIT_YT_MAX)
{
memcpy(&config.units[issmqtt_uid].yts[config.units[issmqtt_uid].ytcount], config.units[i].yts, sizeof(struUnitYT)*config.units[i].ytcount);
config.units[issmqtt_uid].ytcount += config.units[i].ytcount;
}
}
}
}
}
}
return TRUE;
}
#endif
void dumpLogs(void)
{
if (system32.log_enabled)
{ //保存日志
yxbw.DumpYXBW();
soe.DumpSOE();
yklog.DumpYKLog();
ytlog.DumpYTLog();
}
WriteDatabaseCFG();
FILE* pf = fopen("./stop.log", "w+");
if (pf)
{
fwrite(&system32.now, sizeof(unionCP56Time), 1, pf);
fwrite(&system32.timers, sizeof(DWORD), 1, pf);
fclose(pf);
}
}
////////////////////////////////
// 空闲进程
////////////////////////////////
void yk(void)
{
int i;
struYK* pYK;
for (i = 0; i < DATABASE_YK_NUM; i++)
{
pYK = &database.yks[i];
if (pYK->state != YKS_IDLE)
{
if (pYK->result == YKR_IDLE || pYK->result == YKR_OPER)
{
if ((short)(system32.timers - pYK->op_time) > system32.yk_keep)
{
pYK->result = YKR_OVER;
if (pYK->state == YKS_EXEREQ || pYK->state == YKS_EXEING)
{
yklog.PushYKLog(system32.now, i, pYK->value, YKT_EXEOUT, YKS_AUTO, -1);
}
else
{
yklog.PushYKLog(system32.now, i, pYK->value, YKT_SELOUT, YKS_AUTO, -1);
}
}
}
else if (pYK->result == YKR_SUCC)
{
if (pYK->state == YKS_EXEED)
{
if ((short)(system32.timers - pYK->op_time) > system32.yk_keep)
{
pYK->state = YKS_IDLE;
pYK->result = YKR_IDLE;
pYK->op_unit = -1;
}
}
else
{
if ((short)(system32.timers - pYK->op_time) > system32.yk_keep)
{
pYK->result = YKR_OVER;
yklog.PushYKLog(system32.now, i, pYK->value, YKT_SELOUT, YKS_AUTO, -1);
}
}
}
else if (pYK->result == YKR_OVER)
{
if ((short)(system32.timers - pYK->op_time) > (system32.yk_keep + 5))
{
pYK->state = YKS_IDLE;
pYK->result = YKR_IDLE;
pYK->op_unit = -1;
}
}
}
else
{
pYK->op_unit = -1;
}
}
}
void yt(void)
{
int i;
struYT* pYT;
for (i = 0; i < DATABASE_YT_NUM; i++)
{
pYT = &database.yts[i];
if (pYT->state != YTS_IDLE)
{
if (pYT->result == YTR_IDLE || pYT->result == YTR_OPER)
{
if ((short)(system32.timers - pYT->op_time) > system32.yk_keep)
{
pYT->result = YTR_OVER;
if (pYT->state == YTS_EXEREQ || pYT->state == YTS_EXEING)
{
ytlog.PushYTLog(system32.now, i, pYT->value, YTT_EXEOUT, YTS_AUTO, -1);
}
else
{
ytlog.PushYTLog(system32.now, i, pYT->value, YTT_SELOUT, YTS_AUTO, -1);
}
}
}
else if (pYT->result == YTR_SUCC)
{
if (pYT->state == YTS_EXEED)
{
if ((short)(system32.timers - pYT->op_time) > system32.yk_keep)
{
pYT->state = YTS_IDLE;
pYT->result = YTR_IDLE;
pYT->op_unit = -1;
}
}
else
{
if ((short)(system32.timers - pYT->op_time) > system32.yk_keep)
{
pYT->result = YTR_OVER;
ytlog.PushYTLog(system32.now, i, pYT->value, YTT_SELOUT, YTS_AUTO, 1);
}
}
}
else if (pYT->result == YTR_OVER)
{
if ((short)(system32.timers - pYT->op_time) > (system32.yk_keep + 5))
{
pYT->state = YTS_IDLE;
pYT->result = YTR_IDLE;
pYT->op_unit = -1;
}
}
}
else
{
pYT->op_unit = -1;
}
}
}
void* idle_process(void* param)
{
int yxbw_save = 0, yxbw_load = 0;
while (systemRunFlag)
{
sleep(1);
yk();
yt();
//操作保存系统操作Log
if ((system32.timers % 3600) == 0) { //过整点保存
if (system32.log_enabled) {
yxbw.DumpYXBW();
soe.DumpSOE();
yklog.DumpYKLog();
ytlog.DumpYTLog();
}
yxbw_save = yxbw.GetSavePos();
if (yxbw_load != yxbw_save) { //有变位信息
WriteDatabaseCFG();
yxbw_load = yxbw_save;
}
}
for (int i = 0; i < PROCESSES_NUM; i++) {
config.processes[i].softdog++;
if (config.processes[i].softdog > PROCESS_WATCHDOG_TIME) {
config.processes[i].softdog = PROCESS_WATCHDOG_TIME;
} else {
}
}
for (int i = 0; i < UNIT_NUM; i++) {
config.units[i].softdog++;
if (config.units[i].softdog > UNIT_WATCHDOG_TIME) {
config.units[i].softdog = UNIT_WATCHDOG_TIME;
config.units[i].value = SPI_ON;
} else {
config.units[i].value = SPI_OFF;
if ((config.units[i].state & 0x80) != 0x80) {
int j = 0;
for (j = 0; j < config.units[i].yxcount; j++) {
if ((config.units[i].yxs[j].qds & 0x80) == 0x80) break;
}
if (j < config.units[i].yxcount) {
continue;
}
for (j = 0; j < config.units[i].yccount; j++) {
if ((config.units[i].ycs[j].qds & 0x80) == 0x80) break;
}
if (j < config.units[i].yccount) {
continue;
}
config.units[i].state |= 0x80;
}
}
}
}
pthread_exit(0);
return ((void*)0);
}
////////////////////////////////
// 主进程,用于系统时间的更新
////////////////////////////////
void* main_process(void* param)
{
while (systemRunFlag)
{
struct timeval tv;
tv.tv_sec = 0;
//tv.tv_usec = 20000;
tv.tv_usec = TIME_TICKS;
select(0, NULL, NULL, NULL, &tv);
system32.ticks++; //每20ms累加一次
if (get_system_time(&system32.now))
{
system32.now.SU = FALSE;
//if (synchronized)
{
system32.now.IV = FALSE;
}
}
}
pthread_exit(0);
return ((void*)0);
}
void main_process_timer_handler(int signum)
{
system32.ticks++; //每20ms累加一次
if (get_system_time(&system32.now))
{
system32.now.SU = FALSE;
//if (synchronized)
{
system32.now.IV = FALSE;
}
}
}
BOOLEAN initialize_system(BOOLEAN usesqlite, BOOLEAN enable_auto_platform, const char* pathName, char *codeName)
{
if (!InitializeMemory())
{
vLog(LOG_ERROR, "Fail initialize memory!\n");
return FALSE;
}
if (usesqlite)
{
vLog(LOG_DEBUG, "read configuration from sqlite3 db file.\n");
BOOLEAN ret = FALSE;
#if 0
ret = ReadConfigFromSQLite(enable_auto_platform, pathName, codeName);
if (ret)
{
WriteSystemCFG();
WriteNodeCFG();
WriteHardwareCFG();
WriteProcessCFG();
WriteUnitCFG();
WriteStaticUnitCFG();
}
#endif
return ret;
}
else
{
vLog(LOG_DEBUG, "read configuration from struct files.\n");
vLog(LOG_DEBUG, "Loading system config...\n");
if (!ReadSystemCFG())
{
vLog(LOG_ERROR, "Fail load system config!\n");
alarm();
return FALSE;
}
vLog(LOG_DEBUG, "Loading node config...\n");
if (!ReadNodeCFG())
{
vLog(LOG_ERROR, "Fail load node config!\n");
alarm();
return FALSE;
}
vLog(LOG_DEBUG, "Loading database config...\n");
if (!ReadDatabaseCFG())
{
vLog(LOG_ERROR, "Fail load database config!\n");
alarm();
return FALSE;
}
vLog(LOG_DEBUG, "Loading hardware config...\n");
if (!ReadHardwareCFG())
{
vLog(LOG_ERROR, "Fail load hardware config!\n");
alarm();
return FALSE;
}
vLog(LOG_DEBUG, "Loading process config...\n");
if (!ReadProcessCFG())
{
vLog(LOG_ERROR, "Fail load processes config!\n");
alarm();
return FALSE;
}
vLog(LOG_DEBUG, "Loading unit config...\n");
if (!ReadUnitCFG())
{
vLog(LOG_ERROR, "Fail load unit config!\n");
alarm();
return FALSE;
}
vLog(LOG_DEBUG, "Loading static unit config...\n");
if (!ReadStaticUnitCFG())
{
vLog(LOG_ERROR, "Fail load static unit config!\n");
alarm();
return FALSE;
}
}
return TRUE;
}
BOOLEAN destroy_thread(void)
{
int i = 0;
if (!systemRunFlag) return FALSE;
dumpLogs();
systemRunFlag = FALSE;
for (i = 0; i < MAX_THREAD_NUM; i++)
{
if (p_id[i] != 0)
{
vLog(LOG_DEBUG, "waiting for system thread [%d] destroy.\n", i);
pthread_join(p_id[i], NULL);
}
}
return TRUE;
}
BOOLEAN initialize_thread(void)
{
int ret;
pthread_attr_t attr;
systemRunFlag = TRUE;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, MEMERY_1M);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
//pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
ret = pthread_create(&p_id[THREAD_ID_MAIN], &attr, main_process, NULL);
if (ret < 0)
{
vLog(LOG_ERROR, "Create main_process thread error(%d,%s)!\n", errno, strerror(errno));
return FALSE;
}
#if 1
pthread_setname_np(p_id[THREAD_ID_MAIN], "main process");
#endif
ret = pthread_create(&p_id[THREAD_ID_IDLE], &attr, idle_process, NULL);
if (ret < 0)
{
vLog(LOG_ERROR, "Create idle_process thread error(%d,%s)!\n", errno, strerror(errno));
return FALSE;
}
#if 1
pthread_setname_np(p_id[THREAD_ID_IDLE], "idle process");
#endif
pthread_attr_destroy(&attr);
sleep(1);
if (!synchronized)
{
vLog(LOG_DEBUG, "system clock does't synchronized!\n");
}
return TRUE;
}