|
@@ -10,6 +10,7 @@
|
|
|
#include <algorithm>
|
|
|
#include "LogicDevice.h"
|
|
|
using namespace std::placeholders;
|
|
|
+#include "LogLocalHelper.h"
|
|
|
#include "Log4CPP.h"
|
|
|
#include "Helper.JSON.hpp"
|
|
|
#include "CCOS.Dev.Generator.PSG_HD.h"
|
|
@@ -41,8 +42,7 @@ static const int msTimeOut_Lock = 500; //通讯接口锁定时间
|
|
|
static const auto COM_SCFDllName = "libSerialSCF.so";
|
|
|
static const auto TCP_SCFDllName = "libTcpipSCF.so";
|
|
|
static const float msSteps[] = {
|
|
|
- 40, 50, 60, 80, 100, 120, 160,
|
|
|
- 200, 250, 320, 400, 500, 630, 800,
|
|
|
+ 100, 120, 160, 200, 250, 320, 400, 500, 630, 800,
|
|
|
1000, 1250, 1600, 2000
|
|
|
};
|
|
|
|
|
@@ -149,14 +149,12 @@ static bool DecodeFrame(const char* data, int len) {
|
|
|
|
|
|
atomic<int> nsGEN::PSGHDDevice::m_iLoopTime = PSGHD_LoopDefHBTime;
|
|
|
atomic<bool> nsGEN::PSGHDDevice::m_bExtraFlag = false;
|
|
|
-static atomic<bool>HeartBeatFlag = false;
|
|
|
|
|
|
nsGEN::PSGHDDevice::PSGHDDevice(std::shared_ptr <IOEventCenter> center, std::shared_ptr<SCFWrapper> SCF, string configfile)
|
|
|
: super(center)
|
|
|
, superGen()
|
|
|
,m_SCF(SCF)
|
|
|
, m_bConnectFlag(false)
|
|
|
- , HeartBeatFlag(false)
|
|
|
{
|
|
|
m_bExtraFlag = true;
|
|
|
|
|
@@ -477,6 +475,13 @@ RET_STATUS nsGEN::PSGHDDevice::SetFocus(int value)
|
|
|
RET_STATUS nsGEN::PSGHDDevice::Reset()
|
|
|
{
|
|
|
FINFO("clear all errors \n");
|
|
|
+ char errorCodeStr[20];
|
|
|
+ snprintf(errorCodeStr, sizeof(errorCodeStr), "PSGHD_FLT_0");
|
|
|
+ int level = 1;
|
|
|
+
|
|
|
+ m_MSGUnit->DelWarnMessage(errorCodeStr, level, "");
|
|
|
+ m_MSGUnit->DelErrorMessage(errorCodeStr, level, "");
|
|
|
+ FINFO("HWFLT: Fault cleared (fault code 0)");
|
|
|
return HWSend("CLR",3);//仅重置错误状态
|
|
|
}
|
|
|
|
|
@@ -652,14 +657,18 @@ RET_STATUS nsGEN::PSGHDDevice::SetFrameRate(float frameRate)
|
|
|
RET_STATUS nsGEN::PSGHDDevice::SetExpEnable()
|
|
|
{
|
|
|
FINFO("SetExpEnable in\n");
|
|
|
- m_bExpEnable = true;
|
|
|
- return HWSend("ENBL 1", 6);
|
|
|
+ return HWSend("DSW 1", 5);
|
|
|
}
|
|
|
RET_STATUS nsGEN::PSGHDDevice::SetExpDisable()
|
|
|
{
|
|
|
FINFO("SetExpDisable in\n");
|
|
|
- m_bExpEnable = false;
|
|
|
- return HWSend("ENBL 0", 6);
|
|
|
+ return HWSend("DSW 0", 5);
|
|
|
+}
|
|
|
+
|
|
|
+RET_STATUS nsGEN::PSGHDDevice::PrepareAcquisition()
|
|
|
+{
|
|
|
+ FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
|
|
|
+ return RET_STATUS::RET_SUCCEED;
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
@@ -684,32 +693,26 @@ RET_STATUS nsGEN::PSGHDDevice::HWSend(const char* strCommand, int length, bool r
|
|
|
FINFO("Failed - Device not connected");
|
|
|
return RET_STATUS::RET_FAILED;
|
|
|
}
|
|
|
- // 构造协议格式:<STX>CMD<SP>ARG;<CS><CR><LF>
|
|
|
+ // 构造新协议格式:<Command><Data><ETX><Checksum>
|
|
|
char strSendCommand[100] = { 0 };
|
|
|
int len = 0;
|
|
|
- strSendCommand[len++] = 0x02; // STX
|
|
|
|
|
|
// 复制命令部分
|
|
|
memcpy(strSendCommand + len, strCommand, length);
|
|
|
len += length;
|
|
|
|
|
|
- // 添加分号
|
|
|
- strSendCommand[len++] = ';';
|
|
|
+ // 添加ETX结束符(0x03)
|
|
|
+ strSendCommand[len++] = 0x03;
|
|
|
|
|
|
- // 计算校验和(从STX后开始到分号';')
|
|
|
- uint16_t sum = 0;
|
|
|
- for (int i = 1; i < len; i++)
|
|
|
- {
|
|
|
- sum += (uint8_t)strSendCommand[i];
|
|
|
+ // 计算校验和:Command + Data + ETX的累加和取低位
|
|
|
+ uint8_t checksum = 0;
|
|
|
+ for (int i = 0; i < len; i++) { // 从首字节到ETX全部参与计算
|
|
|
+ checksum += (uint8_t)strSendCommand[i];
|
|
|
}
|
|
|
- uint8_t checksum = (uint8_t)(sum & 0xFF);
|
|
|
- checksum = 0x100 - checksum;
|
|
|
- checksum &= 0x7F;
|
|
|
- checksum |= 0x40;
|
|
|
+ checksum &= 0xFF; // 取累加和的低8位
|
|
|
|
|
|
+ // 添加校验和
|
|
|
strSendCommand[len++] = checksum;
|
|
|
- strSendCommand[len++] = 0x0D; // CR
|
|
|
- strSendCommand[len++] = 0x0A; // LF
|
|
|
|
|
|
|
|
|
// 打印数据包前16字节的十六进制(含控制字符)便于调试
|
|
@@ -929,16 +932,16 @@ void nsGEN::PSGHDDevice::OnCallBack()
|
|
|
if (faultCode != 0)
|
|
|
{
|
|
|
static const std::unordered_map<int, std::string> errorMessages = {
|
|
|
- {2, "充电回路异常"}, {3, "存储芯片损坏"}, {136, "灯丝电流1超过限值"},
|
|
|
- {140, "阳极kV超过限值,曝光异常中止"}, {142, "高压发生器或球管打火,曝光异常中止"},
|
|
|
- {165, "高压发生器启动过程中,母线电压过低"}, {205, "高压发生器唤醒或启动过程中二级手闸被按下"},
|
|
|
- {206, "高压发生器电池电量低,请充电"}, {208, "曝光时间间隔较短,请稍后曝光"},
|
|
|
- {209, "曝光过程中禁止调节参数"}, {210, "一级手闸重复触发,请使用单一手闸执行曝光操作"},
|
|
|
- {216, "电池充电中"}, {218, "kV参数超过限值"}, {219, "mA参数超过限值"},
|
|
|
- {220, "ms参数超过限值"}, {229, "高压发生器功率超过限值"}, {230, "球管功率超过限值"},
|
|
|
- {231, "帧频参数超过限值"}, {249, "高压发生器母线电压超过限值"}, {255, "kV建立超时"},
|
|
|
- {259, "曝光过程中提前松开手闸"}, {260, "曝光过程中禁止调节参数"}, {263, "曝光过程中kV过高,曝光异常中止"},
|
|
|
- {267, "曝光过程中mA过低,曝光异常中止"}, {268, "曝光过程中mA过高,曝光异常中止"}, {281, "曝光过程中功率超过限值,曝光异常中止"}
|
|
|
+ {2, "Charging circuit abnormal"}, {3, "Storage chip damaged"}, {136, "Filament current 1 exceeds limit"},
|
|
|
+ {140, "Anode kV exceeds limit, exposure aborted abnormally"}, {142, "High-voltage generator or tube arcing, exposure aborted abnormally"},
|
|
|
+ {165, "Bus voltage too low during high-voltage generator startup"}, {205, "Second-stage handswitch pressed during high-voltage generator wake-up or startup"},
|
|
|
+ {206, "High-voltage generator low battery, please charge"}, {208, "Exposure interval too short, please expose later"},
|
|
|
+ {209, "Parameter adjustment forbidden during exposure"}, {210, "First-stage handswitch repeated triggering, please use a single handswitch for exposure operation"},
|
|
|
+ {216, "Battery being charged"}, {218, "kV parameter exceeds limit"}, {219, "mA parameter exceeds limit"},
|
|
|
+ {220, "ms parameter exceeds limit"}, {229, "High-voltage generator power exceeds limit"}, {230, "Tube power exceeds limit"},
|
|
|
+ {231, "Frame rate parameter exceeds limit"}, {249, "High-voltage generator bus voltage exceeds limit"}, {255, "kV establishment timeout"},
|
|
|
+ {259, "Handswitch released in advance during exposure"}, {260, "Parameter adjustment forbidden during exposure"}, {263, "kV too high during exposure, exposure aborted abnormally"},
|
|
|
+ {267, "mA too low during exposure, exposure aborted abnormally"}, {268, "mA too high during exposure, exposure aborted abnormally"}, {281, "Power exceeds limit during exposure, exposure aborted abnormally"}
|
|
|
};
|
|
|
static const std::unordered_set<int> firstSixErrors = { 2, 3, 136, 140, 142, 165 };
|
|
|
|
|
@@ -975,7 +978,11 @@ void nsGEN::PSGHDDevice::OnCallBack()
|
|
|
FINFO("HWPhase: Invalid data length ({$} < 3), skip", length);
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+ // 设备首次连接时禁止曝光!
|
|
|
+ if (m_isFirstHWPhase) {
|
|
|
+ SetExpDisable();
|
|
|
+ m_isFirstHWPhase = false;
|
|
|
+ }
|
|
|
char phaseCodeStr[4] = { 0 };
|
|
|
strncpy(phaseCodeStr, data, 3);
|
|
|
int phaseCode = atoi(phaseCodeStr);
|
|
@@ -1075,7 +1082,7 @@ void nsGEN::PSGHDDevice::OnCallBack()
|
|
|
{
|
|
|
if (m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_STANDBY))
|
|
|
{
|
|
|
- FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
|
|
|
+ //FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
|
|
|
FINFO("HWEOK: Device ready, status updated to STANDBY");
|
|
|
}
|
|
|
}
|
|
@@ -1083,12 +1090,35 @@ void nsGEN::PSGHDDevice::OnCallBack()
|
|
|
{
|
|
|
if (m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_SLEEP))
|
|
|
{
|
|
|
- FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
|
|
|
+ //FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
|
|
|
FINFO("HWEOK: Device not ready, status updated to SLEEP");
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+ auto HWDSW = [this](const char* data, int length) -> void
|
|
|
+ {
|
|
|
+ if (length < 1) { // 需1字节(X)
|
|
|
+ FINFO("HWDSW: Invalid data length ({$} < 1), skip", length);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ char eokStr = data[0]; // 直接取data[0]
|
|
|
+ bool isReady = (eokStr == '1');
|
|
|
+
|
|
|
+ if (isReady && m_DoseUnit.m_GenState->Get()== nsGEN::AttrKey::GENERATOR_STATUS_STANDBY)
|
|
|
+ {
|
|
|
+ FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
|
|
|
+ FINFO("HWDSW: Device ready, status updated to STANDBY");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_SLEEP);
|
|
|
+ FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
|
|
|
+ FINFO("HWDSW: Device not ready, status updated to SLEEP");
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
auto HWECD = [this](const char* data, int length) -> void
|
|
|
{
|
|
|
if (length < 3) { // 需3字节(XXX)
|
|
@@ -1381,7 +1411,6 @@ void PSGHDDevice::HardwareStatusThread(PSGHDDevice* pParam)
|
|
|
}
|
|
|
|
|
|
PSGHDDevice* pCurGen = pParam;
|
|
|
- pCurGen->HeartBeatFlag = true;
|
|
|
|
|
|
int messageIndex = 0;
|
|
|
|
|
@@ -1392,7 +1421,7 @@ void PSGHDDevice::HardwareStatusThread(PSGHDDevice* pParam)
|
|
|
Sleep(currentLoopTime);
|
|
|
|
|
|
// 每5次循环发送状态查询命令
|
|
|
- if (messageIndex % 5 == 0)
|
|
|
+ if (messageIndex % 5 == 0&& !pCurGen->m_bSleepState)
|
|
|
{
|
|
|
pCurGen->HWSend("RHE", 3);
|
|
|
Sleep(100);
|
|
@@ -1411,7 +1440,6 @@ void PSGHDDevice::HardwareStatusThread(PSGHDDevice* pParam)
|
|
|
}
|
|
|
|
|
|
// 线程退出时重置心跳标志
|
|
|
- pCurGen->HeartBeatFlag = false;
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
@@ -1433,12 +1461,24 @@ nsGEN::PSGHDDriver::~PSGHDDriver()
|
|
|
void nsGEN::PSGHDDriver::Prepare()
|
|
|
{
|
|
|
// 初始化日志系统
|
|
|
- string strLogPath = GetProcessDirectory() + R"(\Conf\log_config.xml)";
|
|
|
- if (!Log4CPP::init("DevPSGHD", "GEN.PSG_HD", strLogPath, true)) {
|
|
|
- std::cerr << "Failed to initialize log system! Using default configuration." << std::endl;
|
|
|
- // 即使配置文件加载失败,也可以继续使用默认配置
|
|
|
+ std::string strLogPath = GetProcessDirectory() + R"(/Conf/log_config.xml)";
|
|
|
+ std::string LogHost = "DevPSGHD";
|
|
|
+ std::string moduleName = "DevPSGHD";
|
|
|
+ bool ret = initLogModule(
|
|
|
+ LogHost, // 主机名(用于日志路径中的{host}占位符)
|
|
|
+ moduleName, // 唯一模块名
|
|
|
+ strLogPath, // 配置文件路径
|
|
|
+ true // 是否输出到控制台(可选)
|
|
|
+ );
|
|
|
+ if (!ret) {
|
|
|
+ std::cerr << "Log init failed!" << std::endl;
|
|
|
+ return;
|
|
|
}
|
|
|
+ PSGHDSetLocalModuleName(moduleName);
|
|
|
+
|
|
|
m_SCFDllName = GetConnectDLL(m_ConfigFileName);
|
|
|
+
|
|
|
+ // 绑定当前动态库的模块名(调用自身实现的接口)
|
|
|
FINFO("Prepare is OK.SCFDllName is {$}", m_SCFDllName);
|
|
|
}
|
|
|
|
|
@@ -1496,38 +1536,84 @@ bool nsGEN::PSGHDDriver::ReConnection()
|
|
|
bool nsGEN::PSGHDDriver::Connect()
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(m_connectionMutex);
|
|
|
+ const auto currentState = m_connectionState.load();
|
|
|
+ auto now = std::chrono::steady_clock::now();
|
|
|
|
|
|
- if (m_connectionState.load() == ConnectionState::Failed) {
|
|
|
- auto now = std::chrono::steady_clock::now();
|
|
|
+ // 1. 处理可重试的失败状态
|
|
|
+ if (currentState == ConnectionState::Failed) {
|
|
|
if ((now - m_lastConnectionAttempt) >= RETRY_INTERVAL && m_connectionRetryCount < MAX_RETRY_COUNT) {
|
|
|
- m_connectionState.store(ConnectionState::Disconnected); // 合法:非const函数
|
|
|
+ m_connectionState = ConnectionState::Disconnected;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return false; // 不满足重试条件,直接返回
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (m_connectionState.load() == ConnectionState::Connected ||
|
|
|
- m_connectionState.load() == ConnectionState::Connecting) {
|
|
|
- FINFO("Already connected or connecting");
|
|
|
+ // 2. 检查无效状态(正在连接/已连接但实际有效)
|
|
|
+ if (currentState == ConnectionState::Connecting) {
|
|
|
+ FINFO("Already connecting (type: {$})",
|
|
|
+ m_currentConnType == ConnectionType::Serial ? "Serial" : "Ethernet");
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (currentState == ConnectionState::Connected && m_scfWrapper && m_scfWrapper->IsConnected()) {
|
|
|
+ FINFO("Already connected (type: {$})",
|
|
|
+ m_currentConnType == ConnectionType::Serial ? "Serial" : "Ethernet");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
- auto now = std::chrono::steady_clock::now();
|
|
|
- if ((now - m_lastConnectionAttempt) < RETRY_INTERVAL && m_connectionRetryCount > 0) {
|
|
|
- FINFO("Too soon to retry connection");
|
|
|
+ // 3. 检查重试间隔
|
|
|
+ if (m_connectionRetryCount > 0 && (now - m_lastConnectionAttempt) < RETRY_INTERVAL) {
|
|
|
+ FINFO("Retry in {$}s (type: {$})",
|
|
|
+ std::chrono::duration_cast<std::chrono::seconds>(RETRY_INTERVAL - (now - m_lastConnectionAttempt)).count(),
|
|
|
+ m_currentConnType == ConnectionType::Serial ? "Serial" : "Ethernet");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- m_connectionState.store(ConnectionState::Connecting);
|
|
|
- m_lastConnectionAttempt = now;
|
|
|
- m_connectionRetryCount++;
|
|
|
+ ResDataObject connParam = GetConnectParam(m_ConfigFileName);
|
|
|
+ std::string connPortStr = "";
|
|
|
+ std::string connTypeStr = (std::string)connParam["type"]; // 从配置读取type字段
|
|
|
+ m_currentConnType = (connTypeStr == "COM") ? ConnectionType::Serial : ConnectionType::Ethernet;
|
|
|
+ if (m_currentConnType == ConnectionType::Serial)
|
|
|
+ {
|
|
|
+ connPortStr = (std::string)connParam["port"];// 从配置读取port字段
|
|
|
+ // 查找配置端口在现有端口列表中的位置
|
|
|
+ auto it = std::find(m_serialPorts.begin(), m_serialPorts.end(), connPortStr);
|
|
|
+
|
|
|
+ if (it == m_serialPorts.end()) {
|
|
|
+ // 配置的端口不在列表中,添加到首位
|
|
|
+ FINFO("Configured serial port {$} not found, adding to front of port list", connPortStr);
|
|
|
+ m_serialPorts.insert(m_serialPorts.begin(), connPortStr);
|
|
|
+ }
|
|
|
+ else if (it != m_serialPorts.begin()) {
|
|
|
+ // 配置的端口存在但不在首位,移动到首位
|
|
|
+ FINFO("Moving configured serial port {$} to front of port list", connPortStr);
|
|
|
+ m_serialPorts.erase(it);
|
|
|
+ m_serialPorts.insert(m_serialPorts.begin(), connPortStr);
|
|
|
+ }
|
|
|
|
|
|
- FINFO("Enter {$},configlef={$}\n", __FUNCTION__, m_ConfigFileName.c_str());
|
|
|
- ResDataObject Connection = GetConnectParam(m_ConfigFileName);
|
|
|
- FINFO("connections:{$} \n", Connection.encode());
|
|
|
+ }
|
|
|
+ // 4. 执行连接流程
|
|
|
+ m_connectionState = ConnectionState::Connecting;
|
|
|
+ m_lastConnectionAttempt = now;
|
|
|
|
|
|
+ std::string connInfo;
|
|
|
try {
|
|
|
+ if (m_currentConnType == ConnectionType::Serial) {
|
|
|
+ // 串口连接:使用当前索引的端口
|
|
|
+ std::string currentPort = m_serialPorts[m_currentSerialPortIndex];
|
|
|
+ connParam.update("port", currentPort.c_str()); // 将当前尝试的端口写入参数
|
|
|
+ connInfo = "Serial (port: " + currentPort + ")";
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // 网口连接:直接使用配置参数
|
|
|
+ connInfo = "Ethernet (ip: " + std::string(connParam["ip"]) + ")";
|
|
|
+ }
|
|
|
+
|
|
|
+ FINFO("Enter Connect ({$}), config: {$}", connInfo, connParam.encode());
|
|
|
+
|
|
|
if (!m_scfWrapper->Initialize(m_SCFDllName)) {
|
|
|
- FINFO("Failed to initialize SCFWrapper: {$}", m_scfWrapper->GetLastError());
|
|
|
- m_connectionState.store(ConnectionState::Failed);
|
|
|
+ FINFO("Init failed: {$}", m_scfWrapper->GetLastError());
|
|
|
+ m_connectionState = ConnectionState::Failed;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -1535,27 +1621,49 @@ bool nsGEN::PSGHDDriver::Connect()
|
|
|
this->Dequeue(data, length);
|
|
|
});
|
|
|
|
|
|
- auto erCode = m_scfWrapper->Connect(Connection, &PSGHDDriver::callbackPackageProcess, SCF_NORMAL_TRANSFER, 3000);
|
|
|
- if (erCode != SCF_SUCCEED) {
|
|
|
- FINFO("Connection failed with error code: {$}", erCode);
|
|
|
- m_connectionState.store(ConnectionState::Failed);
|
|
|
- return false;
|
|
|
- }
|
|
|
+ auto erCode = m_scfWrapper->Connect(connParam, &PSGHDDriver::callbackPackageProcess, SCF_NORMAL_TRANSFER, 3000);
|
|
|
+ if (erCode != SCF_SUCCEED || !m_scfWrapper->StartAutoReceive()) {
|
|
|
+ FINFO("Connect failed (code: {$}) for {$}", erCode, connInfo);
|
|
|
+ m_scfWrapper->Disconnect();
|
|
|
+ m_connectionState = ConnectionState::Failed;
|
|
|
+ // 串口连接:未遍历完所有端口时,优先切换端口重试(不计入总重试次数)
|
|
|
+ if (m_currentConnType == ConnectionType::Serial) {
|
|
|
+ int nextIndex = (m_currentSerialPortIndex + 1) % m_serialPorts.size();
|
|
|
+ // 判断是否已遍历所有端口(当前索引是最后一个时,nextIndex会回到0)
|
|
|
+ bool allPortsTried = (nextIndex == 0);
|
|
|
+
|
|
|
+ if (!allPortsTried) {
|
|
|
+ // 未遍历完所有端口:切换到下一端口,不增加重试计数
|
|
|
+ m_currentSerialPortIndex = nextIndex;
|
|
|
+ m_connectionRetryCount = 0;
|
|
|
+ FINFO("Trying next serial port: {$}", m_serialPorts[nextIndex]);
|
|
|
+ return false; // 触发外部线程立即尝试下一端口
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // 已遍历所有端口:重置到第一个端口,增加重试计数(进入间隔等待)
|
|
|
+ m_currentSerialPortIndex = 0;
|
|
|
+ m_connectionRetryCount++;
|
|
|
+ FINFO("All serial ports tried, retry count: {$}/{$}", m_connectionRetryCount, MAX_RETRY_COUNT);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- if (!m_scfWrapper->StartAutoReceive()) {
|
|
|
- FINFO("Failed to start auto receive");
|
|
|
- m_connectionState.store(ConnectionState::Failed);
|
|
|
+ // 所有端口失败(串口)或网口失败,才增加总重试计数
|
|
|
+ m_connectionRetryCount++;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- m_connectionState.store(ConnectionState::Connected);
|
|
|
+ // 连接成功:重置状态
|
|
|
+ m_connectionState = ConnectionState::Connected;
|
|
|
m_connectionRetryCount = 0;
|
|
|
- FINFO("Connection established successfully");
|
|
|
+ m_currentSerialPortIndex = 0; // 重置串口端口索引
|
|
|
+ FINFO("Connected successfully ({$})", connInfo);
|
|
|
return true;
|
|
|
}
|
|
|
catch (const std::exception& e) {
|
|
|
- FINFO("Exception during connection: {$}", e.what());
|
|
|
- m_connectionState.store(ConnectionState::Failed);
|
|
|
+ FINFO("Exception for {$}: {$}", connInfo, e.what());
|
|
|
+ m_connectionState = ConnectionState::Failed;
|
|
|
+ m_connectionRetryCount++;
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
@@ -1578,31 +1686,39 @@ void nsGEN::PSGHDDriver::FireNotify(int code, std::string key, std::string conte
|
|
|
|
|
|
bool nsGEN::PSGHDDriver::isConnected() const
|
|
|
{
|
|
|
- FINFO("isConnected in");
|
|
|
- if (m_connectionState.load() == ConnectionState::Connecting) {
|
|
|
- FINFO("Connection in progress, skipping additional connect attempts");
|
|
|
- return true;
|
|
|
- }
|
|
|
+ const auto state = m_connectionState.load();
|
|
|
|
|
|
- if (m_scfWrapper && m_scfWrapper->IsConnected()) {
|
|
|
- FINFO("m_scfWrapper->IsConnected()");
|
|
|
+ // 1. 连接中/实际已连接:返回true(无需重连)
|
|
|
+ if (state == ConnectionState::Connecting || (m_scfWrapper && m_scfWrapper->IsConnected())) {
|
|
|
+ FINFO(state == ConnectionState::Connecting ? "Connecting in progress" : "Already connected");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
- auto now = std::chrono::steady_clock::now();
|
|
|
- auto timeSinceLastAttempt = now - m_lastConnectionAttempt;
|
|
|
+ // 2. 失败状态处理:判断是否允许重试
|
|
|
+ if (state == ConnectionState::Failed) {
|
|
|
+ auto now = std::chrono::steady_clock::now();
|
|
|
+ const auto timeSinceLast = now - m_lastConnectionAttempt;
|
|
|
|
|
|
- if (m_connectionState.load() == ConnectionState::Failed) {
|
|
|
- if (timeSinceLastAttempt < RETRY_INTERVAL) {
|
|
|
- FINFO("Too soon to retry connection");
|
|
|
- return false;
|
|
|
+ // 2.1 达到最大重试次数,但超过重置间隔:重置计数,允许重新重试
|
|
|
+ if (m_connectionRetryCount >= MAX_RETRY_COUNT && timeSinceLast >= RESET_RETRY_AFTER) {
|
|
|
+ FINFO("Max retries reached, resetting count after {$}s",
|
|
|
+ std::chrono::duration_cast<std::chrono::seconds>(timeSinceLast).count());
|
|
|
+ m_connectionRetryCount = 0; // 重置计数(因mutable修饰,const函数可修改)
|
|
|
}
|
|
|
- if (m_connectionRetryCount >= MAX_RETRY_COUNT) {
|
|
|
- FINFO("Max connection retries exceeded");
|
|
|
- return false;
|
|
|
+
|
|
|
+ // 2.2 不适合重连(时间未到 或 次数仍超限):返回true阻止重连
|
|
|
+ if (timeSinceLast < RETRY_INTERVAL || m_connectionRetryCount >= MAX_RETRY_COUNT) {
|
|
|
+ FINFO(timeSinceLast < RETRY_INTERVAL ?
|
|
|
+ "Retry later ({$}s)" : "Max retries, waiting {$}s to reset",
|
|
|
+ std::chrono::duration_cast<std::chrono::seconds>(
|
|
|
+ timeSinceLast < RETRY_INTERVAL ? RETRY_INTERVAL - timeSinceLast : RESET_RETRY_AFTER - timeSinceLast
|
|
|
+ ).count()
|
|
|
+ );
|
|
|
+ return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 3. 其他情况(适合重连):返回false触发Connect()
|
|
|
return false;
|
|
|
}
|
|
|
|