2025-01-16 16:17:01 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @file: $RCSfile: save2json.h,v $
|
|
|
|
|
|
* @brief: $IEC 61850 Protocol
|
|
|
|
|
|
*
|
|
|
|
|
|
* @version: $Revision: 1.5 $
|
|
|
|
|
|
* @date: $Date: 2018/12/23 12:39:52 $
|
|
|
|
|
|
* @author: $Author: lizhongming $
|
|
|
|
|
|
* @state: $State: Exp $
|
|
|
|
|
|
*
|
|
|
|
|
|
* @latest: $Id: save2json.h,v 1.5 2018/12/23 12:39:52 lizhongming Exp $
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef SAVE2DB_8ue3hy0923r_H
|
|
|
|
|
|
#define SAVE2DB_8ue3hy0923r_H
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
|
#endif
|
|
|
|
|
|
extern int g_front_seg_index;
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
#include <map>
|
|
|
|
|
|
#include <list>
|
|
|
|
|
|
|
2025-03-06 15:24:49 +08:00
|
|
|
|
#include "../mms/db_interface.h"
|
2025-01-16 16:17:01 +08:00
|
|
|
|
#include <QThread>
|
|
|
|
|
|
|
|
|
|
|
|
//lnk20250106
|
2025-05-09 16:53:07 +08:00
|
|
|
|
#include "../rocketmq/SimpleProducer.h"
|
|
|
|
|
|
//日志功能
|
2025-02-28 16:28:15 +08:00
|
|
|
|
#include "../cfg_parse/custom_printf.h"//lnk20250225
|
|
|
|
|
|
#include <csignal>
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
2025-01-16 16:17:01 +08:00
|
|
|
|
#include <QTcpServer>
|
|
|
|
|
|
#include <QTcpSocket>
|
|
|
|
|
|
#include <QMutex>
|
|
|
|
|
|
#include <QMutexLocker>
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
#include <QTimer>
|
|
|
|
|
|
#include <QCoreApplication>
|
|
|
|
|
|
#include <QStringList>
|
|
|
|
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
extern int G_TEST_NUM;
|
2025-05-28 16:09:15 +08:00
|
|
|
|
extern int G_TEST_TYPE;
|
2025-01-16 16:17:01 +08:00
|
|
|
|
extern void ledger(const char* terminal_id = NULL,QIODevice* outputDevice = NULL);
|
2025-02-10 17:03:15 +08:00
|
|
|
|
extern void value_print(const char *variableName, QTcpSocket *clientSocket);
|
2025-01-16 16:17:01 +08:00
|
|
|
|
extern int TEST_PORT;
|
|
|
|
|
|
|
2025-03-06 18:41:48 +08:00
|
|
|
|
extern void redirectErrorOutput(bool enable);
|
|
|
|
|
|
extern void redirectWarnOutput(bool enable);
|
|
|
|
|
|
extern void redirectNormalOutput(bool enable);
|
|
|
|
|
|
extern void redirectDebugOutput(bool enable);
|
2025-01-16 16:17:01 +08:00
|
|
|
|
|
|
|
|
|
|
class KafkaSendThread : public QThread
|
|
|
|
|
|
{
|
|
|
|
|
|
protected:
|
|
|
|
|
|
void run();
|
|
|
|
|
|
};
|
2025-05-09 16:53:07 +08:00
|
|
|
|
//WW 2023-08-22 增加数据库线程和WebSocket线程
|
2025-01-16 16:17:01 +08:00
|
|
|
|
|
|
|
|
|
|
class WebSocketThread : public QThread
|
|
|
|
|
|
{
|
|
|
|
|
|
protected:
|
|
|
|
|
|
void run();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//lnk20241029
|
|
|
|
|
|
class WebhttpThread : public QThread
|
|
|
|
|
|
{
|
|
|
|
|
|
protected:
|
|
|
|
|
|
void run();
|
|
|
|
|
|
};
|
|
|
|
|
|
class httpThread : public QThread
|
|
|
|
|
|
{
|
|
|
|
|
|
protected:
|
|
|
|
|
|
void run();
|
|
|
|
|
|
};
|
2025-04-29 15:05:36 +08:00
|
|
|
|
|
2025-01-16 16:17:01 +08:00
|
|
|
|
//lnk20250106
|
2025-02-28 16:28:15 +08:00
|
|
|
|
extern bool showinshellflag;
|
|
|
|
|
|
|
2025-03-04 17:29:04 +08:00
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
void doMonitorTaskmain(void);
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// ====================== Telnet 常量定义 ======================
|
|
|
|
|
|
// Telnet 命令字节:
|
2025-03-05 17:47:47 +08:00
|
|
|
|
#define IAC 255 // Interpret As Command
|
|
|
|
|
|
#define DONT 254
|
|
|
|
|
|
#define TELDO 253
|
|
|
|
|
|
#define WONT 252
|
|
|
|
|
|
#define WILL 251
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// Telnet 选项常量:
|
|
|
|
|
|
#define TELOPT_ECHO 1 // 回显
|
2025-03-05 17:47:47 +08:00
|
|
|
|
#define TELOPT_SUPPRESS_GO_AHEAD 3 // SGA
|
2025-05-09 16:53:07 +08:00
|
|
|
|
#define TELOPT_LINEMODE 34 // 行模式
|
2025-03-05 17:47:47 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
2025-05-09 16:53:07 +08:00
|
|
|
|
* @brief Worker类:包含启动服务器、处理Telnet交互等逻辑
|
2025-03-05 17:47:47 +08:00
|
|
|
|
*/
|
2025-01-16 16:17:01 +08:00
|
|
|
|
class Worker : public QObject
|
|
|
|
|
|
{
|
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
2025-02-27 16:28:04 +08:00
|
|
|
|
Worker(QObject *parent = NULL)
|
|
|
|
|
|
: QObject(parent),
|
|
|
|
|
|
server(NULL),
|
|
|
|
|
|
TEST_NUM(G_TEST_NUM),
|
2025-05-28 16:09:15 +08:00
|
|
|
|
TEST_TYPE(G_TEST_TYPE),
|
2025-02-27 16:28:04 +08:00
|
|
|
|
timer(NULL),
|
2025-02-28 16:28:15 +08:00
|
|
|
|
historyIndex(-1),
|
2025-03-07 18:27:03 +08:00
|
|
|
|
stopViewLog(true),
|
|
|
|
|
|
g_stopTelnetTest(true),
|
2025-02-28 16:28:15 +08:00
|
|
|
|
activeClient(NULL)
|
2025-02-27 16:28:04 +08:00
|
|
|
|
{
|
2025-02-10 17:03:15 +08:00
|
|
|
|
}
|
2025-02-27 16:28:04 +08:00
|
|
|
|
|
2025-01-16 16:17:01 +08:00
|
|
|
|
~Worker() {
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 清理定时器和服务器
|
2025-02-10 17:03:15 +08:00
|
|
|
|
stopServer();
|
2025-01-16 16:17:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-28 16:28:15 +08:00
|
|
|
|
void handleViewLogCommand(const QString& command, QTcpSocket* clientSocket);
|
2025-03-07 18:27:03 +08:00
|
|
|
|
int init_ping_telnet(QTcpSocket* clientSocket, int& ip_count, int& telnet_count);
|
|
|
|
|
|
void telnetetst(QTcpSocket* clientSocket);
|
2025-03-05 17:47:47 +08:00
|
|
|
|
|
2025-02-28 16:28:15 +08:00
|
|
|
|
|
2025-01-16 16:17:01 +08:00
|
|
|
|
public slots:
|
2025-03-05 17:47:47 +08:00
|
|
|
|
/**
|
2025-05-09 16:53:07 +08:00
|
|
|
|
* @brief 启动服务器
|
2025-03-05 17:47:47 +08:00
|
|
|
|
*/
|
2025-01-16 16:17:01 +08:00
|
|
|
|
void startServer() {
|
2025-02-10 17:03:15 +08:00
|
|
|
|
if (server) {
|
|
|
|
|
|
qDebug() << "Server is already running!";
|
2025-05-09 16:53:07 +08:00
|
|
|
|
return; // 防止重复启动服务器
|
2025-02-10 17:03:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 创建 QTcpServer 并设置信号与槽
|
2025-02-10 17:03:15 +08:00
|
|
|
|
server = new QTcpServer(this);
|
2025-01-16 16:17:01 +08:00
|
|
|
|
connect(server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 尝试监听端口
|
2025-01-16 16:17:01 +08:00
|
|
|
|
if (!server->listen(QHostAddress::Any, TEST_PORT)) {
|
|
|
|
|
|
std::cout << "Server failed to start!" << std::endl;
|
|
|
|
|
|
qDebug() << "Server failed to start!";
|
|
|
|
|
|
emit serverError();
|
|
|
|
|
|
return;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
std::cout << "Server is running on port " << TEST_PORT << std::endl;
|
|
|
|
|
|
qDebug() << QString("Server is running on port %1").arg(TEST_PORT);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 创建并启动定时器
|
2025-01-16 16:17:01 +08:00
|
|
|
|
timer = new QTimer(this);
|
|
|
|
|
|
connect(timer, SIGNAL(timeout()), this, SLOT(doPeriodicTask()));
|
2025-05-09 16:53:07 +08:00
|
|
|
|
timer->start(60000); // 每60秒触发一次
|
2025-01-16 16:17:01 +08:00
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 开启另一个周期函数用来替换主线程的监控
|
2025-03-04 17:29:04 +08:00
|
|
|
|
QTimer *monitorTimer = new QTimer(this);
|
|
|
|
|
|
connect(monitorTimer, SIGNAL(timeout()), this, SLOT(doMonitorTask()));
|
2025-05-09 16:53:07 +08:00
|
|
|
|
monitorTimer->start(1000); // 每1秒触发一次
|
2025-03-04 17:29:04 +08:00
|
|
|
|
|
2025-03-05 17:47:47 +08:00
|
|
|
|
std::cout << "Timer started, event loop running in thread: "
|
|
|
|
|
|
<< QThread::currentThreadId() << std::endl;
|
2025-01-16 16:17:01 +08:00
|
|
|
|
qDebug() << "Timer started, event loop running in thread:" << QThread::currentThreadId();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-05 17:47:47 +08:00
|
|
|
|
/**
|
2025-05-09 16:53:07 +08:00
|
|
|
|
* @brief 停止服务器
|
2025-03-05 17:47:47 +08:00
|
|
|
|
*/
|
2025-02-10 17:03:15 +08:00
|
|
|
|
void stopServer() {
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 停止服务器并清理资源
|
2025-02-10 17:03:15 +08:00
|
|
|
|
if (server) {
|
|
|
|
|
|
server->close();
|
|
|
|
|
|
delete server;
|
|
|
|
|
|
server = NULL;
|
|
|
|
|
|
qDebug() << "Server stopped.";
|
|
|
|
|
|
}
|
2025-02-27 16:28:04 +08:00
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 停止定时器
|
2025-02-10 17:03:15 +08:00
|
|
|
|
if (timer) {
|
|
|
|
|
|
timer->stop();
|
|
|
|
|
|
delete timer;
|
|
|
|
|
|
timer = NULL;
|
|
|
|
|
|
qDebug() << "Timer stopped.";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-05 17:47:47 +08:00
|
|
|
|
/**
|
2025-05-09 16:53:07 +08:00
|
|
|
|
* @brief 设置TEST_NUM
|
2025-03-05 17:47:47 +08:00
|
|
|
|
*/
|
2025-01-16 16:17:01 +08:00
|
|
|
|
void setTestNum(int num) {
|
|
|
|
|
|
QMutexLocker locker(&mutex);
|
|
|
|
|
|
TEST_NUM = num;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-28 16:09:15 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 设置TEST_TYPE
|
|
|
|
|
|
*/
|
|
|
|
|
|
void setTestType(int type) {
|
|
|
|
|
|
QMutexLocker locker(&mutex);
|
|
|
|
|
|
TEST_TYPE = type;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-06 18:41:48 +08:00
|
|
|
|
void setTestlog(bool flag) {
|
|
|
|
|
|
redirectErrorOutput(flag);
|
|
|
|
|
|
redirectWarnOutput(flag);
|
|
|
|
|
|
redirectNormalOutput(flag);
|
|
|
|
|
|
redirectDebugOutput(flag);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-01-16 16:17:01 +08:00
|
|
|
|
private slots:
|
2025-03-05 17:47:47 +08:00
|
|
|
|
/**
|
2025-05-09 16:53:07 +08:00
|
|
|
|
* @brief 定时任务
|
2025-03-05 17:47:47 +08:00
|
|
|
|
*/
|
2025-01-16 16:17:01 +08:00
|
|
|
|
void doPeriodicTask() {
|
|
|
|
|
|
QMutexLocker locker(&mutex);
|
2025-05-28 16:09:15 +08:00
|
|
|
|
std::cout << "Executing TEST_NUM is " << TEST_NUM << "Executing TEST_TYPE is " << TEST_TYPE << std::endl;
|
|
|
|
|
|
qDebug() << "doPeriodicTask() called. TEST_NUM = " << TEST_NUM << "Executing TEST_TYPE is " << TEST_TYPE;
|
2025-01-16 16:17:01 +08:00
|
|
|
|
|
|
|
|
|
|
if (TEST_NUM != 0) {
|
|
|
|
|
|
qDebug() << "Executing rocketmq_test_300()";
|
|
|
|
|
|
std::cout << "Executing rocketmq_test_300()\n";
|
2025-05-28 16:09:15 +08:00
|
|
|
|
rocketmq_test_300(TEST_NUM, g_front_seg_index,TEST_TYPE);
|
2025-01-16 16:17:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-05 17:47:47 +08:00
|
|
|
|
/**
|
2025-05-09 16:53:07 +08:00
|
|
|
|
* @brief 监控任务
|
2025-03-05 17:47:47 +08:00
|
|
|
|
*/
|
2025-03-04 17:29:04 +08:00
|
|
|
|
void doMonitorTask() {
|
|
|
|
|
|
doMonitorTaskmain();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-05 17:47:47 +08:00
|
|
|
|
/**
|
2025-05-09 16:53:07 +08:00
|
|
|
|
* @brief 当有新客户端连接时处理
|
2025-03-05 17:47:47 +08:00
|
|
|
|
*/
|
2025-01-16 16:17:01 +08:00
|
|
|
|
void onNewConnection() {
|
|
|
|
|
|
if (!server) return;
|
|
|
|
|
|
|
|
|
|
|
|
QTcpSocket *clientSocket = server->nextPendingConnection();
|
|
|
|
|
|
qDebug() << "New connection established!";
|
|
|
|
|
|
std::cout << "New connection established!\n";
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 绑定 readyRead / disconnected
|
2025-01-16 16:17:01 +08:00
|
|
|
|
connect(clientSocket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
|
2025-02-27 16:28:04 +08:00
|
|
|
|
connect(clientSocket, SIGNAL(disconnected()), clientSocket, SLOT(deleteLater()));
|
2025-01-16 16:17:01 +08:00
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 发送 Telnet 协商
|
2025-03-05 17:47:47 +08:00
|
|
|
|
sendTelnetNegotiation(clientSocket);
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 发送欢迎信息和提示符
|
2025-01-16 16:17:01 +08:00
|
|
|
|
if (clientSocket) {
|
|
|
|
|
|
std::cout << "clientSocket OK\n";
|
2025-03-05 17:47:47 +08:00
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Welcome to the test shell. Type 'help' for available commands.\r\n");
|
2025-05-09 16:53:07 +08:00
|
|
|
|
printPrompt(clientSocket); // 统一打印提示符
|
2025-01-16 16:17:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-27 16:28:04 +08:00
|
|
|
|
/**
|
2025-05-09 16:53:07 +08:00
|
|
|
|
* @brief 处理客户端发送的Telnet数据
|
2025-02-27 16:28:04 +08:00
|
|
|
|
*/
|
2025-01-16 16:17:01 +08:00
|
|
|
|
void onReadyRead() {
|
|
|
|
|
|
QTcpSocket *clientSocket = qobject_cast<QTcpSocket *>(sender());
|
|
|
|
|
|
if (!clientSocket) {
|
|
|
|
|
|
std::cout << "Invalid socket\n";
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QByteArray data = clientSocket->readAll();
|
2025-02-27 16:28:04 +08:00
|
|
|
|
for (int i = 0; i < data.size(); ++i) {
|
2025-03-05 17:47:47 +08:00
|
|
|
|
unsigned char c = static_cast<unsigned char>(data[i]);
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 如果检测到 IAC(255),说明是 Telnet 协商指令
|
2025-03-05 17:47:47 +08:00
|
|
|
|
if (c == IAC) {
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 简单跳过 TELDO/DONT/WILL/WONT + option
|
2025-03-05 17:47:47 +08:00
|
|
|
|
if (i + 1 < data.size()) {
|
|
|
|
|
|
unsigned char cmd = static_cast<unsigned char>(data[i+1]);
|
|
|
|
|
|
if (cmd == TELDO || cmd == DONT || cmd == WILL || cmd == WONT) {
|
2025-05-09 16:53:07 +08:00
|
|
|
|
i += 2; // 跳过这2字节
|
2025-03-05 17:47:47 +08:00
|
|
|
|
} else {
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 遇到其它情况(比如IAC SB),此处仅简单跳过一个字节
|
2025-03-05 17:47:47 +08:00
|
|
|
|
i += 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
2025-02-27 16:28:04 +08:00
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 1) 处理 '`' 退出 viewlog 和ping
|
2025-03-06 15:24:49 +08:00
|
|
|
|
if (c == '`') {
|
|
|
|
|
|
std::cout << "Received '`' from shell socket! Exiting viewlog...\n";
|
2025-02-28 16:28:15 +08:00
|
|
|
|
if (activeClient == clientSocket) {
|
2025-03-05 17:47:47 +08:00
|
|
|
|
stopViewLog = true;
|
2025-03-06 18:41:48 +08:00
|
|
|
|
g_stopTelnetTest = true;
|
2025-03-05 17:47:47 +08:00
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("\r\nLog view stopped. Returning to shell.\r\n");
|
|
|
|
|
|
printPrompt(clientSocket);
|
2025-02-27 16:28:04 +08:00
|
|
|
|
}
|
2025-03-05 17:47:47 +08:00
|
|
|
|
return;
|
2025-02-28 16:28:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 2) 回车换行:执行命令
|
2025-03-05 17:47:47 +08:00
|
|
|
|
if (c == '\r' || c == '\n') {
|
|
|
|
|
|
if (!currentCommand.isEmpty()) {
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 加到历史
|
2025-03-05 17:47:47 +08:00
|
|
|
|
if (commandHistory.isEmpty() || commandHistory.last() != currentCommand) {
|
|
|
|
|
|
commandHistory.append(currentCommand);
|
2025-02-28 16:28:15 +08:00
|
|
|
|
}
|
2025-03-05 17:47:47 +08:00
|
|
|
|
historyIndex = commandHistory.size();
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 执行命令时,忽略前后空白
|
2025-03-05 17:47:47 +08:00
|
|
|
|
//QString trimmedCmd = currentCommand.trimmed();
|
|
|
|
|
|
currentCommand.remove(0, 1);
|
|
|
|
|
|
processCommand(currentCommand, clientSocket);
|
|
|
|
|
|
|
|
|
|
|
|
currentCommand.clear();
|
|
|
|
|
|
} else {
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 空行 => 仅打印新的提示符
|
2025-03-05 17:47:47 +08:00
|
|
|
|
printPrompt(clientSocket);
|
|
|
|
|
|
}
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 3) 方向键
|
2025-03-05 17:47:47 +08:00
|
|
|
|
if (c == '\x1b') {
|
|
|
|
|
|
if (i + 2 < data.size() && data[i+1] == '[') {
|
|
|
|
|
|
char arrow = data[i+2];
|
|
|
|
|
|
if (arrow == 'A') {
|
|
|
|
|
|
handleUpArrow(clientSocket);
|
|
|
|
|
|
} else if (arrow == 'B') {
|
|
|
|
|
|
handleDownArrow(clientSocket);
|
2025-02-28 16:28:15 +08:00
|
|
|
|
}
|
2025-03-05 17:47:47 +08:00
|
|
|
|
i += 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 假设提示符固定为 "> ",提示符长度为2
|
2025-03-06 15:24:49 +08:00
|
|
|
|
const int promptLength = 1;
|
2025-03-06 10:32:40 +08:00
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 4) 退格键
|
2025-03-05 17:47:47 +08:00
|
|
|
|
if (c == '\x7f' || c == '\b') {
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 仅当 currentCommand 的长度大于提示符长度时,允许删除字符
|
2025-03-06 10:32:40 +08:00
|
|
|
|
if (currentCommand.length() > promptLength) {
|
2025-03-05 17:47:47 +08:00
|
|
|
|
currentCommand.chop(1);
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 回显退格:用 "\b \b" 来擦除屏幕上最后一个字符
|
2025-03-05 17:47:47 +08:00
|
|
|
|
clientSocket->write("\b \b");
|
2025-02-27 16:28:04 +08:00
|
|
|
|
clientSocket->flush();
|
2025-03-05 17:47:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
continue;
|
2025-02-27 16:28:04 +08:00
|
|
|
|
}
|
2025-02-28 16:28:15 +08:00
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 5) 普通字符
|
2025-03-05 17:47:47 +08:00
|
|
|
|
currentCommand.append(static_cast<char>(c));
|
|
|
|
|
|
clientSocket->write((const char*)&c, 1);
|
|
|
|
|
|
clientSocket->flush();
|
2025-02-10 17:03:15 +08:00
|
|
|
|
}
|
2025-02-27 16:28:04 +08:00
|
|
|
|
}
|
2025-02-10 17:03:15 +08:00
|
|
|
|
|
2025-02-27 16:28:04 +08:00
|
|
|
|
signals:
|
|
|
|
|
|
void serverError();
|
2025-02-11 18:23:19 +08:00
|
|
|
|
|
2025-02-27 16:28:04 +08:00
|
|
|
|
private:
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// ========== Telnet 协商函数 ==========
|
2025-03-05 17:47:47 +08:00
|
|
|
|
void sendTelnetNegotiation(QTcpSocket *socket)
|
|
|
|
|
|
{
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 发送 WILL ECHO / WILL SUPPRESS-GO-AHEAD / DONT LINEMODE
|
2025-03-05 17:47:47 +08:00
|
|
|
|
static const unsigned char will_echo[3] = { IAC, WILL, TELOPT_ECHO };
|
|
|
|
|
|
static const unsigned char will_sga[3] = { IAC, WILL, TELOPT_SUPPRESS_GO_AHEAD };
|
|
|
|
|
|
static const unsigned char dont_linemode[3] = { IAC, DONT, TELOPT_LINEMODE };
|
|
|
|
|
|
|
|
|
|
|
|
socket->write(reinterpret_cast<const char*>(will_echo), 3);
|
|
|
|
|
|
socket->write(reinterpret_cast<const char*>(will_sga), 3);
|
|
|
|
|
|
socket->write(reinterpret_cast<const char*>(dont_linemode), 3);
|
|
|
|
|
|
socket->flush();
|
|
|
|
|
|
}
|
2025-02-28 16:28:15 +08:00
|
|
|
|
|
2025-03-05 17:47:47 +08:00
|
|
|
|
/**
|
2025-05-09 16:53:07 +08:00
|
|
|
|
* @brief 打印提示符:统一使用\r\n换行,并且打印"> "于行首
|
2025-03-05 17:47:47 +08:00
|
|
|
|
*/
|
|
|
|
|
|
void printPrompt(QTcpSocket *clientSocket)
|
|
|
|
|
|
{
|
2025-03-06 10:32:40 +08:00
|
|
|
|
clientSocket->write("\n\r\x1B[K> ");
|
2025-03-05 17:47:47 +08:00
|
|
|
|
clientSocket->flush();
|
|
|
|
|
|
}
|
2025-02-27 16:28:04 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
2025-05-09 16:53:07 +08:00
|
|
|
|
* @brief 执行一条命令(已被trimmed)
|
2025-02-27 16:28:04 +08:00
|
|
|
|
*/
|
2025-03-05 17:47:47 +08:00
|
|
|
|
void processCommand(const QString &cmd, QTcpSocket *clientSocket) {
|
|
|
|
|
|
qDebug() << "Received command:" << cmd;
|
|
|
|
|
|
std::cout << "Received command: " << cmd.toStdString() << "\n";
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 命令解析
|
2025-03-05 17:47:47 +08:00
|
|
|
|
if (cmd == "help") {
|
|
|
|
|
|
QString helpText = "Available commands:\r\n";
|
|
|
|
|
|
helpText += "TEST_NUM=<num> - Set the TEST_NUM\r\n";
|
2025-05-28 16:09:15 +08:00
|
|
|
|
helpText += "TEST_TYPE=<num> - Set the TEST_TYPE 0:use ledger,1:use number\r\n";
|
2025-03-06 18:41:48 +08:00
|
|
|
|
helpText += "LOG=<bool> - Set the LOG\r\n";
|
|
|
|
|
|
helpText += "telnettest - Set the telnettest\r\n";
|
2025-03-05 17:47:47 +08:00
|
|
|
|
helpText += "rc - Execute rocketmq_test_rc\r\n";
|
|
|
|
|
|
helpText += "rt - Execute rocketmq_test_rt\r\n";
|
|
|
|
|
|
helpText += "ud - Execute rocketmq_test_ud\r\n";
|
|
|
|
|
|
helpText += "set - Execute rocketmq_test_set\r\n";
|
|
|
|
|
|
helpText += "only - Execute rocketmq_test_only\r\n";
|
|
|
|
|
|
helpText += "log - Execute rocketmq_test_log\r\n";
|
2025-03-06 15:24:49 +08:00
|
|
|
|
helpText += "soe - Execute http_test_soe\r\n";
|
|
|
|
|
|
helpText += "qvvr - Execute http_test_qvvr\r\n";
|
|
|
|
|
|
helpText += "connect - Execute http_test_connect\r\n";
|
2025-03-05 17:47:47 +08:00
|
|
|
|
helpText += "ledger <id> - Execute ledger with optional terminal_id\r\n";
|
|
|
|
|
|
helpText += "viewlog <level> - View logs (ERROR, WARN, NORMAL, DEBUG)\r\n";
|
2025-03-06 10:32:40 +08:00
|
|
|
|
helpText += "value <valuename> - Execute value print with valuename : frontindex remtable iedcount frontfun log init\r\n";
|
2025-03-05 17:47:47 +08:00
|
|
|
|
helpText += "exit - Exit the shell\r\n";
|
|
|
|
|
|
helpText += "help - Show this help message\r\n";
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
2025-02-10 17:03:15 +08:00
|
|
|
|
clientSocket->write(helpText.toUtf8());
|
|
|
|
|
|
}
|
2025-03-05 17:47:47 +08:00
|
|
|
|
else if (cmd.startsWith("viewlog")) {
|
2025-02-28 16:28:15 +08:00
|
|
|
|
showinshellflag = true;
|
2025-03-05 17:47:47 +08:00
|
|
|
|
handleViewLogCommand(cmd, clientSocket);
|
2025-02-28 16:28:15 +08:00
|
|
|
|
}
|
2025-03-05 17:47:47 +08:00
|
|
|
|
else if (cmd.startsWith("TEST_NUM=")) {
|
2025-01-16 16:17:01 +08:00
|
|
|
|
bool ok;
|
2025-03-05 17:47:47 +08:00
|
|
|
|
int num = cmd.mid(9).toInt(&ok);
|
2025-01-16 16:17:01 +08:00
|
|
|
|
if (ok) {
|
2025-03-05 17:47:47 +08:00
|
|
|
|
setTestNum(num);
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("TEST_NUM updated\r\n");
|
2025-01-16 16:17:01 +08:00
|
|
|
|
} else {
|
2025-03-05 17:47:47 +08:00
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Invalid number\r\n");
|
2025-01-16 16:17:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-05-28 16:09:15 +08:00
|
|
|
|
else if (cmd.startsWith("TEST_TYPE=")) {
|
|
|
|
|
|
bool ok;
|
|
|
|
|
|
int type = cmd.mid(10).toInt(&ok);
|
|
|
|
|
|
if (ok) {
|
|
|
|
|
|
setTestType(type);
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("TEST_TYPE updated\r\n");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Invalid type\r\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-03-06 18:41:48 +08:00
|
|
|
|
else if (cmd.startsWith("LOG=")) {
|
|
|
|
|
|
bool ok;
|
|
|
|
|
|
bool flag = cmd.mid(4).toInt(&ok);
|
|
|
|
|
|
if (ok) {
|
|
|
|
|
|
setTestlog(flag);
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
2025-05-28 16:09:15 +08:00
|
|
|
|
clientSocket->write("LOG updated\r\n");
|
2025-03-06 18:41:48 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Invalid number\r\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (cmd.startsWith("telnettest")) {
|
2025-03-07 18:27:03 +08:00
|
|
|
|
g_stopTelnetTest = false;
|
2025-03-06 18:41:48 +08:00
|
|
|
|
telnetetst(clientSocket);
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Executed telnettest warning!!! it woont stop until finish!!!\r\n");
|
|
|
|
|
|
}
|
2025-03-05 17:47:47 +08:00
|
|
|
|
else if (cmd.startsWith("rc")) {
|
|
|
|
|
|
rocketmq_test_rc();
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Executed rocketmq_test_rc\r\n");
|
2025-01-16 16:17:01 +08:00
|
|
|
|
}
|
2025-03-05 17:47:47 +08:00
|
|
|
|
else if (cmd.startsWith("rt")) {
|
|
|
|
|
|
rocketmq_test_rt();
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Executed rocketmq_test_rt\r\n");
|
2025-01-16 16:17:01 +08:00
|
|
|
|
}
|
2025-03-05 17:47:47 +08:00
|
|
|
|
else if (cmd.startsWith("ud")) {
|
|
|
|
|
|
rocketmq_test_ud();
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Executed rocketmq_test_ud\r\n");
|
2025-01-16 16:17:01 +08:00
|
|
|
|
}
|
2025-03-05 17:47:47 +08:00
|
|
|
|
else if (cmd.startsWith("set")) {
|
|
|
|
|
|
rocketmq_test_set();
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Executed rocketmq_test_set\r\n");
|
2025-01-16 16:17:01 +08:00
|
|
|
|
}
|
2025-03-05 17:47:47 +08:00
|
|
|
|
else if (cmd.startsWith("only")) {
|
|
|
|
|
|
rocketmq_test_only();
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Executed rocketmq_test_only\r\n");
|
2025-02-27 16:28:04 +08:00
|
|
|
|
}
|
2025-03-05 17:47:47 +08:00
|
|
|
|
else if (cmd.startsWith("log")) {
|
|
|
|
|
|
rocketmq_test_log();
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Executed rocketmq_test_log\r\n");
|
2025-02-11 18:23:19 +08:00
|
|
|
|
}
|
2025-03-06 15:24:49 +08:00
|
|
|
|
else if (cmd.startsWith("soe")) {
|
|
|
|
|
|
SOEFileWeb_test();
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Executed http_test_soe\r\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (cmd.startsWith("qvvr")) {
|
|
|
|
|
|
qvvr_test();
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Executed http_test_qvvr\r\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (cmd.startsWith("connect")) {
|
|
|
|
|
|
comflag_test();
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Executed http_test_connect\r\n");
|
|
|
|
|
|
}
|
2025-03-05 17:47:47 +08:00
|
|
|
|
else if (cmd.startsWith("ledger")) {
|
|
|
|
|
|
QStringList parts = cmd.split(" ");
|
|
|
|
|
|
if (parts.size() > 1) {
|
2025-01-16 16:17:01 +08:00
|
|
|
|
QString terminalId = parts[1];
|
2025-03-05 17:47:47 +08:00
|
|
|
|
ledger(terminalId.toStdString().c_str(), clientSocket);
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Executed ledger with terminal_id\r\n");
|
2025-01-16 16:17:01 +08:00
|
|
|
|
} else {
|
2025-03-05 17:47:47 +08:00
|
|
|
|
ledger(NULL, clientSocket);
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Executed ledger without parameters\r\n");
|
2025-01-16 16:17:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-03-05 17:47:47 +08:00
|
|
|
|
else if (cmd.startsWith("value")) {
|
|
|
|
|
|
QStringList parts = cmd.split(" ");
|
2025-02-27 16:28:04 +08:00
|
|
|
|
if (parts.size() > 1) {
|
2025-03-06 10:32:40 +08:00
|
|
|
|
QString variableName = parts[1];
|
2025-03-05 17:47:47 +08:00
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Executed value with variable name: " + variableName.toUtf8() + "\r\n");
|
2025-03-06 10:32:40 +08:00
|
|
|
|
value_print(variableName.toStdString().c_str(), clientSocket);
|
2025-02-10 17:03:15 +08:00
|
|
|
|
} else {
|
2025-03-05 17:47:47 +08:00
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Please provide a variable name\r\n");
|
2025-02-10 17:03:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-03-05 17:47:47 +08:00
|
|
|
|
else if (cmd == "exit") {
|
|
|
|
|
|
clientSocket->write("\r\x1B[K");
|
|
|
|
|
|
clientSocket->write("Goodbye! Exiting shell...\r\n");
|
2025-02-10 17:03:15 +08:00
|
|
|
|
clientSocket->flush();
|
2025-03-05 17:47:47 +08:00
|
|
|
|
clientSocket->disconnectFromHost();
|
|
|
|
|
|
clientSocket->waitForDisconnected();
|
2025-02-27 16:28:04 +08:00
|
|
|
|
return;
|
2025-02-10 17:03:15 +08:00
|
|
|
|
}
|
2025-01-16 16:17:01 +08:00
|
|
|
|
else {
|
2025-03-05 17:47:47 +08:00
|
|
|
|
clientSocket->write("\r\x1B[K> ");
|
|
|
|
|
|
clientSocket->write("Unknown command\r\n");
|
|
|
|
|
|
clientSocket->flush();
|
2025-01-16 16:17:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 命令处理结束后,打印提示符
|
2025-03-05 17:47:47 +08:00
|
|
|
|
printPrompt(clientSocket);
|
2025-01-16 16:17:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-27 16:28:04 +08:00
|
|
|
|
/**
|
2025-05-09 16:53:07 +08:00
|
|
|
|
* @brief 上箭头:历史命令回溯
|
2025-02-27 16:28:04 +08:00
|
|
|
|
*/
|
|
|
|
|
|
void handleUpArrow(QTcpSocket *clientSocket) {
|
|
|
|
|
|
if (!commandHistory.isEmpty() && historyIndex > 0) {
|
|
|
|
|
|
historyIndex--;
|
|
|
|
|
|
currentCommand = commandHistory[historyIndex];
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 清行:\r回到行首 + \x1B[K清除光标后文字
|
2025-03-05 17:47:47 +08:00
|
|
|
|
clientSocket->write("\r\x1B[K> ");
|
|
|
|
|
|
clientSocket->write(currentCommand.toUtf8());
|
2025-02-27 16:28:04 +08:00
|
|
|
|
clientSocket->flush();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2025-05-09 16:53:07 +08:00
|
|
|
|
* @brief 下箭头:历史命令前进
|
2025-02-27 16:28:04 +08:00
|
|
|
|
*/
|
|
|
|
|
|
void handleDownArrow(QTcpSocket *clientSocket) {
|
|
|
|
|
|
if (!commandHistory.isEmpty() && historyIndex < commandHistory.size() - 1) {
|
|
|
|
|
|
historyIndex++;
|
|
|
|
|
|
currentCommand = commandHistory[historyIndex];
|
|
|
|
|
|
|
2025-03-05 17:47:47 +08:00
|
|
|
|
clientSocket->write("\r\x1B[K> ");
|
|
|
|
|
|
clientSocket->write(currentCommand.toUtf8());
|
2025-02-27 16:28:04 +08:00
|
|
|
|
clientSocket->flush();
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (historyIndex == commandHistory.size() - 1) {
|
|
|
|
|
|
historyIndex = commandHistory.size();
|
|
|
|
|
|
currentCommand.clear();
|
|
|
|
|
|
|
2025-03-05 17:47:47 +08:00
|
|
|
|
clientSocket->write("\r\x1B[K> ");
|
2025-02-27 16:28:04 +08:00
|
|
|
|
clientSocket->flush();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-01-16 16:17:01 +08:00
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
QTcpServer *server;
|
|
|
|
|
|
QTimer *timer;
|
|
|
|
|
|
int TEST_NUM;
|
2025-05-28 16:09:15 +08:00
|
|
|
|
int TEST_TYPE;
|
2025-01-16 16:17:01 +08:00
|
|
|
|
QMutex mutex;
|
2025-02-27 16:28:04 +08:00
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// 历史命令相关
|
|
|
|
|
|
QList<QString> commandHistory; // 存储历史命令
|
|
|
|
|
|
int historyIndex; // 当前历史命令索引
|
|
|
|
|
|
QString currentCommand; // 当前正在输入的命令
|
2025-03-05 17:47:47 +08:00
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
// viewlog 相关
|
2025-03-06 18:41:48 +08:00
|
|
|
|
bool stopViewLog;
|
2025-05-09 16:53:07 +08:00
|
|
|
|
//ping相关
|
2025-03-06 18:41:48 +08:00
|
|
|
|
bool g_stopTelnetTest;
|
2025-03-05 17:47:47 +08:00
|
|
|
|
QTcpSocket* activeClient;
|
2025-01-16 16:17:01 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2025-02-10 17:03:15 +08:00
|
|
|
|
|
2025-01-16 16:17:01 +08:00
|
|
|
|
//lnk20241213
|
|
|
|
|
|
class mqconsumerThread : public QThread
|
|
|
|
|
|
{
|
|
|
|
|
|
protected:
|
|
|
|
|
|
void run();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
class OnTimerThread : public QThread//定时线程
|
2025-01-16 16:17:01 +08:00
|
|
|
|
{
|
|
|
|
|
|
protected:
|
|
|
|
|
|
void run();
|
|
|
|
|
|
};
|
|
|
|
|
|
//WW 2023-08-22 end
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2025-05-09 16:53:07 +08:00
|
|
|
|
//lnk20250106添加台账结构
|
2025-01-16 16:17:01 +08:00
|
|
|
|
typedef struct terminal terminal;
|
|
|
|
|
|
typedef struct monitor monitor;
|
2025-05-09 16:53:07 +08:00
|
|
|
|
struct monitor // 监测点台账
|
2025-01-16 16:17:01 +08:00
|
|
|
|
{
|
|
|
|
|
|
char monitor_id[64];
|
|
|
|
|
|
char terminal_code[64];
|
|
|
|
|
|
char monitor_name[64];
|
|
|
|
|
|
char logical_device_seq[64];
|
|
|
|
|
|
char voltage_level[64];
|
|
|
|
|
|
char terminal_connect[64];
|
|
|
|
|
|
char timestamp[64];
|
|
|
|
|
|
char status[255];
|
|
|
|
|
|
|
|
|
|
|
|
};
|
2025-05-09 16:53:07 +08:00
|
|
|
|
struct terminal // 终端台账
|
2025-01-16 16:17:01 +08:00
|
|
|
|
{
|
2025-05-09 16:53:07 +08:00
|
|
|
|
|
|
|
|
|
|
char guid[128];
|
|
|
|
|
|
|
2025-01-16 16:17:01 +08:00
|
|
|
|
char terminal_id[64];
|
|
|
|
|
|
char terminal_code[64];
|
|
|
|
|
|
char org_name[64];
|
|
|
|
|
|
char maint_name[64];
|
|
|
|
|
|
char station_name[64];
|
|
|
|
|
|
char tmnl_factory[64];
|
|
|
|
|
|
char tmnl_status[64];
|
|
|
|
|
|
char dev_type[64];
|
|
|
|
|
|
char dev_key[255];
|
|
|
|
|
|
char dev_series[255];
|
2025-05-09 16:53:07 +08:00
|
|
|
|
char processNo[64]; //lnk20250210进程号
|
2025-01-16 16:17:01 +08:00
|
|
|
|
char addr_str[64];
|
|
|
|
|
|
char port[64];
|
|
|
|
|
|
char timestamp[64];
|
2025-05-09 16:53:07 +08:00
|
|
|
|
monitor line[10]; // 最多 10 个监测点
|
2025-01-16 16:17:01 +08:00
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
#endif //SAVE2DB_8ue3hy0923r_H
|