-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSocketManager.h
More file actions
130 lines (108 loc) · 3.87 KB
/
Copy pathSocketManager.h
File metadata and controls
130 lines (108 loc) · 3.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#pragma once
#include <Iec104TcpSocket.h>
#include <qabstractsocket.h>
#include <qglobal.h>
#include <qobject.h>
#include <qobjectdefs.h>
#include <qstring.h>
#include <qthread.h>
#include <qtimer.h>
#include "iec104/iec104_log.h"
#include "iec104/iec104_types.h"
class SocketManager : public QObject
{
Q_OBJECT
public:
struct CommandData
{
bool cb888Mode;
QString leCmdAddressLow;
QString leCmdAddressMid;
QString leCmdAddressHigh;
QString leCmdAddress;
QString leASDUAddr;
QString cbCmdAsdu;
QString cbCmdDuration;
QString leCmdValue;
bool cbSBO;
};
enum class ServerType
{
Primary,
Backup
};
struct ServerConfig
{
QString host;
quint16 port;
};
SocketManager(QObject* parent = nullptr);
~SocketManager();
// Управление
void start(); // Начинаем подключение к первичному серверу
void stop(); // Полная остановка (явная команда отключиться)
void reconnect(); // Принудительное переподключение
iec104_log* logQueue();
//Защищенные сокет операции (межпоточные)
void requestUpdate();
void requestConnect(QString ip, quint16 port);
void requestDisconnect();
void requestAbort();
void requestGI();
void requestSendData(CommandData data);
// Статус
bool isConnected() const;
ServerType currentServer() const;
signals:
void connected(ServerType server); // Подключились к серверу
void disconnected(); // Отключились (по любой причине)
void errorOccurred(const QString& error); // Ошибка с человеческим текстом
void stopped(); // Полная остановка по команде
void signal_dataIndication(const QVector<iec_obj>& objects);
void signal_interrogationActConfIndication();
void signal_interrogationActTermIndication();
void signal_commandActRespIndication(const iec_obj& obj);
void signal_userprocAPDU(iec_apdu* papdu, int sz);
private slots:
void onSocketConnected();
void onSocketDisconnected();
void onSocketError(QAbstractSocket::SocketError error);
void onReconnectTimer();
void onPrimaryCheckerConnected();
void onPrimaryCheckerDisconnected();
void onPrimaryCheckerError(QAbstractSocket::SocketError error);
void onPrimaryCheckTimeout();
private:
enum class State
{
Idle, // Неактивен (остановлен)
Connecting, // В процессе подключения
Connected, // Подключен и работает
Reconnecting // Переподключение (пауза)
};
// Внутренние методы
void connectTo(ServerType server);
void switchToNextServer();
void scheduleReconnect(int delayMs = 1000);
void resetConnectionAttempts();
void shutdownProtocolThread();
void startPrimaryChecker();
void stopPrimaryChecker();
void checkPrimaryServer();
void switchFromBackupToPrimary();
private:
// Данные
Iec104Socket* m_socket = nullptr;
QTimer* m_reconnectTimer = nullptr;
QTcpSocket* m_primaryChecker = nullptr;
QTimer* m_primaryCheckTimer = nullptr;
bool m_switchingToPrimary = false;
ServerConfig m_primaryServer;
ServerConfig m_backupServer;
bool m_hasBackupServer = false;
State m_state = State::Idle;
ServerType m_currentServer = ServerType::Primary;
int m_connectionAttempts = 0; // Попытки подряд к одному серверу
bool m_stopRequested = false; // Флаг явной остановки
QThread m_protocolThread;
};