From bdf0dc4cb183d3fec40e1d51b3bb94b7e53d0a55 Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期日, 04 一月 2026 10:45:07 +0800
Subject: [PATCH] 1.修复报文字段差异风险: S1F3:项目用 getSubItemU4(0) 取 SVID;日志里有 U2 的情况,可能导致解析失败后回退成 SV=0。 S6F11:项目发送 DATAID(U4) + CEID(U4);日志样例里第一个字段是 U2,可能存在类型/字段定义不一致。
---
SourceCode/Bond/Servo/HsmsPassive.cpp | 390 +++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 359 insertions(+), 31 deletions(-)
diff --git a/SourceCode/Bond/Servo/HsmsPassive.cpp b/SourceCode/Bond/Servo/HsmsPassive.cpp
index 3315b32..ae7ef22 100644
--- a/SourceCode/Bond/Servo/HsmsPassive.cpp
+++ b/SourceCode/Bond/Servo/HsmsPassive.cpp
@@ -8,6 +8,8 @@
#include <time.h>
#include <stdlib.h>
#include <string.h>
+#include <algorithm>
+#include <set>
#include <regex>
@@ -373,6 +375,17 @@
return m_variabels;
}
+unsigned int CHsmsPassive::getMaxVariableId() const
+{
+ unsigned int maxId = 0;
+ for (auto item : m_variabels) {
+ if (item && item->getVarialbleId() > maxId) {
+ maxId = item->getVarialbleId();
+ }
+ }
+ return maxId;
+}
+
SERVO::CVariable* CHsmsPassive::getVariable(int variableId)
{
for (auto item : m_variabels) {
@@ -453,7 +466,93 @@
if (filepath.empty()) return -2;
- // 鍐欏洖鏂囦欢锛屼繚鎸佸師缂栫爜锛圲TF-8 鎴栨湰鍦扮紪鐮侊級
+ return writeVariablesToFile(filepath);
+}
+
+void CHsmsPassive::setVariableValue(const char* pszName, __int64 value)
+{
+ auto v = getVariable(pszName);
+ if (v != nullptr) {
+ v->setValue(value);
+ }
+}
+
+void CHsmsPassive::setVariableValue(const char* pszName, const char* value)
+{
+ auto v = getVariable(pszName);
+ if (v != nullptr) {
+ v->setValue(value);
+ }
+}
+
+void CHsmsPassive::setVariableValue(const char* pszName, std::vector<SERVO::CVariable>& vars)
+{
+ auto v = getVariable(pszName);
+ if (v != nullptr) {
+ v->setValue(vars);
+ }
+}
+
+static bool isValidFormat(const std::string& fmt)
+{
+ static const std::set<std::string> allow = { "U1","U2","I2","A20","A50","L" };
+ return allow.count(fmt) > 0;
+}
+
+int CHsmsPassive::addVariable(const char* pszName, const char* pszFormat, const char* pszRemark, int& outId)
+{
+ if (pszName == nullptr || pszFormat == nullptr) return -1;
+ std::string fmt = pszFormat;
+ std::transform(fmt.begin(), fmt.end(), fmt.begin(), ::toupper);
+ if (!isValidFormat(fmt)) return -2;
+
+ Lock();
+ int maxId = 0;
+ for (auto v : m_variabels) {
+ if (v != nullptr && v->getVarialbleId() > maxId) {
+ maxId = v->getVarialbleId();
+ }
+ }
+ outId = maxId + 1;
+
+ SERVO::CVariable* pNew = new SERVO::CVariable(std::to_string(outId).c_str(), pszName, fmt.c_str(), pszRemark ? pszRemark : "");
+ m_variabels.push_back(pNew);
+ auto filepath = m_strVariableFilepath;
+ Unlock();
+
+ if (filepath.empty()) return -3;
+ return writeVariablesToFile(filepath);
+}
+
+int CHsmsPassive::updateVariable(int variableId, const char* pszName, const char* pszFormat, const char* pszRemark)
+{
+ if (pszName == nullptr || pszFormat == nullptr) return -1;
+ std::string fmt = pszFormat;
+ std::transform(fmt.begin(), fmt.end(), fmt.begin(), ::toupper);
+ if (!isValidFormat(fmt)) return -2;
+
+ Lock();
+ auto it = std::find_if(m_variabels.begin(), m_variabels.end(), [=](SERVO::CVariable* v) {
+ return v != nullptr && v->getVarialbleId() == variableId;
+ });
+ if (it == m_variabels.end()) {
+ Unlock();
+ return -4;
+ }
+ (*it)->setName(pszName);
+ (*it)->setFormat(fmt.c_str());
+ (*it)->setRemark(pszRemark ? pszRemark : "");
+ auto filepath = m_strVariableFilepath;
+ Unlock();
+
+ if (filepath.empty()) return -3;
+ return writeVariablesToFile(filepath);
+}
+
+int CHsmsPassive::writeVariablesToFile(const std::string& filepath)
+{
+ if (filepath.empty()) return -3;
+
CFile file;
if (!file.Open(filepath.c_str(), CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone)) {
return -3;
@@ -499,32 +598,11 @@
return 0;
}
-void CHsmsPassive::setVariableValue(const char* pszName, __int64 value)
-{
- auto v = getVariable(pszName);
- if (v != nullptr) {
- v->setValue(value);
- }
-}
-
-void CHsmsPassive::setVariableValue(const char* pszName, const char* value)
-{
- auto v = getVariable(pszName);
- if (v != nullptr) {
- v->setValue(value);
- }
-}
-
-void CHsmsPassive::setVariableValue(const char* pszName, std::vector<SERVO::CVariable>& vars)
-{
- auto v = getVariable(pszName);
- if (v != nullptr) {
- v->setValue(vars);
- }
-}
-
int CHsmsPassive::loadReports(const char* pszFilepath)
{
+ m_strReportFilepath = pszFilepath;
+ m_bReportUtf8 = false;
+ m_bReportUtf8Bom = false;
// 鍏煎 UTF-8/BOM 涓庢湰鍦扮紪鐮佽鍙�
CFile file;
if (!file.Open(pszFilepath, CFile::modeRead | CFile::shareDenyNone)) {
@@ -548,6 +626,8 @@
// UTF-8 BOM
if (nLen >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) {
offset = 3;
+ m_bReportUtf8 = true;
+ m_bReportUtf8Bom = true;
}
// UTF-16 LE BOM
@@ -577,6 +657,7 @@
MultiByteToWideChar(CP_UTF8, 0, buffer.data() + off,
static_cast<int>(buffer.size() - off), temp.data(), need);
content = temp.c_str();
+ m_bReportUtf8 = true;
return true;
};
@@ -653,6 +734,17 @@
return m_reports;
}
+unsigned int CHsmsPassive::getMaxReportId() const
+{
+ unsigned int maxId = 0;
+ for (auto item : m_reports) {
+ if (item && item->getReportId() > maxId) {
+ maxId = item->getReportId();
+ }
+ }
+ return maxId;
+}
+
SERVO::CReport* CHsmsPassive::getReport(int rptid)
{
for (auto item : m_reports) {
@@ -677,6 +769,49 @@
return false;
}
+int CHsmsPassive::deleteReport(int rptid)
+{
+ if (!removeReport(rptid)) {
+ return -1;
+ }
+ return writeReportsToFile(m_strReportFilepath);
+}
+
+int CHsmsPassive::addReport(int rptid, const std::vector<unsigned int>& vids)
+{
+ if (getReport(rptid) != nullptr) {
+ return -1;
+ }
+ SERVO::CReport* pReport = new SERVO::CReport(rptid, vids);
+ for (auto vid : vids) {
+ SERVO::CVariable* pVariable = getVariable((int)vid);
+ if (pVariable != nullptr) {
+ pReport->addVariable(pVariable);
+ }
+ }
+ m_reports.push_back(pReport);
+ return writeReportsToFile(m_strReportFilepath);
+}
+
+int CHsmsPassive::updateReport(int rptid, const std::vector<unsigned int>& vids)
+{
+ for (auto iter = m_reports.begin(); iter != m_reports.end(); ++iter) {
+ if ((*iter)->getReportId() == rptid) {
+ delete (*iter);
+ SERVO::CReport* pReport = new SERVO::CReport(rptid, vids);
+ for (auto vid : vids) {
+ SERVO::CVariable* pVariable = getVariable((int)vid);
+ if (pVariable != nullptr) {
+ pReport->addVariable(pVariable);
+ }
+ }
+ *iter = pReport;
+ return writeReportsToFile(m_strReportFilepath);
+ }
+ }
+ return -1;
+}
+
void CHsmsPassive::clearAllReport()
{
for (auto item : m_reports) {
@@ -685,8 +820,64 @@
m_reports.clear();
}
+int CHsmsPassive::writeReportsToFile(const std::string& filepath)
+{
+ if (filepath.empty()) return -1;
+
+ CFile file;
+ if (!file.Open(filepath.c_str(), CFile::modeCreate | CFile::modeWrite)) {
+ return -1;
+ }
+
+ if (m_bReportUtf8 && m_bReportUtf8Bom) {
+ const BYTE bom[3] = { 0xEF, 0xBB, 0xBF };
+ file.Write(bom, 3);
+ }
+
+ // header
+ const std::string headerAnsi = "RPTID,(VID1,VID2,...)\r\n";
+ if (m_bReportUtf8) {
+ CStringA header = AnsiToUtf8(headerAnsi);
+ file.Write(header.GetString(), header.GetLength());
+ }
+ else {
+ file.Write(headerAnsi.data(), (UINT)headerAnsi.size());
+ }
+
+ for (auto rpt : m_reports) {
+ if (rpt == nullptr) continue;
+ std::string line;
+ line.reserve(64);
+ line += std::to_string(rpt->getReportId());
+ line += ",(";
+
+ const auto& vids = rpt->getVids();
+ for (size_t i = 0; i < vids.size(); ++i) {
+ line += std::to_string(vids[i]);
+ if (i + 1 < vids.size()) {
+ line.push_back(',');
+ }
+ }
+ line += ")\r\n";
+
+ if (m_bReportUtf8) {
+ CStringA out = AnsiToUtf8(line);
+ file.Write(out.GetString(), out.GetLength());
+ }
+ else {
+ file.Write(line.data(), (UINT)line.size());
+ }
+ }
+
+ file.Close();
+ return 0;
+}
+
int CHsmsPassive::loadCollectionEvents(const char* pszFilepath)
{
+ m_strCollectionEventFilepath = pszFilepath;
+ m_bCollectionUtf8 = false;
+ m_bCollectionUtf8Bom = false;
CFile file;
if (!file.Open(pszFilepath, CFile::modeRead | CFile::shareDenyNone)) {
return -1;
@@ -709,6 +900,8 @@
// UTF-8 BOM
if (nLen >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) {
offset = 3;
+ m_bCollectionUtf8 = true;
+ m_bCollectionUtf8Bom = true;
}
// UTF-16 LE BOM
@@ -738,6 +931,7 @@
MultiByteToWideChar(CP_UTF8, 0, buffer.data() + off,
static_cast<int>(buffer.size() - off), temp.data(), need);
content = temp.c_str();
+ m_bCollectionUtf8 = true;
return true;
};
@@ -826,6 +1020,64 @@
return m_collectionEvents;
}
+unsigned int CHsmsPassive::getMaxCollectionEventId() const
+{
+ unsigned int maxId = 0;
+ for (auto item : m_collectionEvents) {
+ if (item && item->getEventId() > maxId) {
+ maxId = item->getEventId();
+ }
+ }
+ return maxId;
+}
+
+int CHsmsPassive::deleteCollectionEvent(unsigned short CEID)
+{
+ for (auto iter = m_collectionEvents.begin(); iter != m_collectionEvents.end(); ++iter) {
+ if ((*iter)->getEventId() == CEID) {
+ delete (*iter);
+ m_collectionEvents.erase(iter);
+ return writeCollectionEventsToFile(m_strCollectionEventFilepath);
+ }
+ }
+ return -1;
+}
+
+int CHsmsPassive::addCollectionEvent(unsigned int CEID, const char* name, const char* desc, const std::vector<unsigned int>& rptids)
+{
+ if (getEvent((unsigned short)CEID) != nullptr) {
+ return -1;
+ }
+ auto* pEvent = new SERVO::CCollectionEvent(CEID, name, desc, const_cast<std::vector<unsigned int>&>(rptids));
+ for (auto rptid : rptids) {
+ SERVO::CReport* pReport = getReport((int)rptid);
+ if (pReport != nullptr) {
+ pEvent->addReport(pReport);
+ }
+ }
+ m_collectionEvents.push_back(pEvent);
+ return writeCollectionEventsToFile(m_strCollectionEventFilepath);
+}
+
+int CHsmsPassive::updateCollectionEvent(unsigned int CEID, const char* name, const char* desc, const std::vector<unsigned int>& rptids)
+{
+ for (auto iter = m_collectionEvents.begin(); iter != m_collectionEvents.end(); ++iter) {
+ if ((*iter)->getEventId() == CEID) {
+ delete (*iter);
+ auto* pEvent = new SERVO::CCollectionEvent(CEID, name, desc, const_cast<std::vector<unsigned int>&>(rptids));
+ for (auto rptid : rptids) {
+ SERVO::CReport* pReport = getReport((int)rptid);
+ if (pReport != nullptr) {
+ pEvent->addReport(pReport);
+ }
+ }
+ *iter = pEvent;
+ return writeCollectionEventsToFile(m_strCollectionEventFilepath);
+ }
+ }
+ return -1;
+}
+
void CHsmsPassive::clearAllCollectionEvent()
{
for (auto item : m_collectionEvents) {
@@ -865,6 +1117,62 @@
}
return result;
+}
+
+int CHsmsPassive::writeCollectionEventsToFile(const std::string& filepath)
+{
+ if (filepath.empty()) return -1;
+
+ CFile file;
+ if (!file.Open(filepath.c_str(), CFile::modeCreate | CFile::modeWrite)) {
+ return -1;
+ }
+
+ if (m_bCollectionUtf8 && m_bCollectionUtf8Bom) {
+ const BYTE bom[3] = { 0xEF, 0xBB, 0xBF };
+ file.Write(bom, 3);
+ }
+
+ const std::string headerAnsi = "CEID,CE Name,Descriptions,Attached RPTID\r\n";
+ if (m_bCollectionUtf8) {
+ CStringA header = AnsiToUtf8(headerAnsi);
+ file.Write(header.GetString(), header.GetLength());
+ }
+ else {
+ file.Write(headerAnsi.data(), (UINT)headerAnsi.size());
+ }
+
+ for (auto ev : m_collectionEvents) {
+ if (ev == nullptr) continue;
+ std::string line;
+ line.reserve(128);
+ line += std::to_string(ev->getEventId());
+ line.push_back(',');
+ line += ev->getName();
+ line.push_back(',');
+ line += ev->getDescription();
+ line.push_back(',');
+ line.push_back('(');
+ auto rptIds = ev->getReportIds();
+ for (size_t i = 0; i < rptIds.size(); ++i) {
+ line += std::to_string(rptIds[i]);
+ if (i + 1 < rptIds.size()) {
+ line.push_back(',');
+ }
+ }
+ line += ")\r\n";
+
+ if (m_bCollectionUtf8) {
+ CStringA out = AnsiToUtf8(line);
+ file.Write(out.GetString(), out.GetLength());
+ }
+ else {
+ file.Write(line.data(), (UINT)line.size());
+ }
+ }
+
+ file.Close();
+ return 0;
}
int CHsmsPassive::init(CModel* pModel, const char* pszName, unsigned int port)
@@ -1309,18 +1617,18 @@
ASSERT(pMessage);
unsigned char SVU1 = 0;
- unsigned int SVID = 0;
+ unsigned short SVID = 0;
ISECS2Item* pBody = pRecv->getBody();
if (pBody == nullptr || pBody->getType() != SITYPE::L) {
pMessage->getBody()->addU1Item(SVU1, "SV");
goto MYREPLY;
}
- if (!pBody->getSubItemU4(0, SVID)) {
+ if (!pBody->getSubItemU2(0, SVID)) {
pMessage->getBody()->addU1Item(SVU1, "SV");
goto MYREPLY;
}
- SERVO::CVariable* pVariable = getVariable(SVID);
+ SERVO::CVariable* pVariable = getVariable((int)SVID);
if (pVariable == nullptr) {
pMessage->getBody()->addU1Item(SVU1, "SV");
goto MYREPLY;
@@ -2151,7 +2459,7 @@
}
// S6F11
-static unsigned int DATAID = 1;
+static unsigned short DATAID = 0;
int CHsmsPassive::requestEventReportSend(unsigned int CEID)
{
SERVO::CCollectionEvent* pEvent = getEvent(CEID);
@@ -2171,7 +2479,8 @@
HSMS_Create1Message(pMessage, m_nSessionId, 6 | REPLY, 11, ++m_nSystemByte);
ASSERT(pMessage);
ISECS2Item* pItem = pMessage->getBody();
- pItem->addU4Item(++DATAID, "DATAID");
+ // pItem->addU2Item(++DATAID, "DATAID"); // 鏍规嵁鍒殑鏃ュ織鏄剧ずDATAID鎭掍负0锛屾墍浠ユ垜浠厛鐓т娇鐢�0
+ pItem->addU2Item(0, "DATAID");
pItem->addU4Item(CEID, "CEID");
ISECS2Item* pItemList1 = pItem->addItem();
ISECS2Item* pItemList2 = pItemList1->addItem();
@@ -2215,6 +2524,21 @@
return requestEventReportSend("CarrierID_Readed");
}
+int CHsmsPassive::requestEventReportSend_CheckSlotMap()
+{
+ return requestEventReportSend("CheckSlotMap");
+}
+
+int CHsmsPassive::requestEventReportSend_SlotMapVerificationOK()
+{
+ return requestEventReportSend("SlotMapVerificationOK");
+}
+
+int CHsmsPassive::requestEventReportSend_SlotMapVerificationNG()
+{
+ return requestEventReportSend("SlotMapVerificationNG");
+}
+
int CHsmsPassive::requestEventReportSend_Port_Unload_Ready()
{
return requestEventReportSend("Port_Unload_Ready");
@@ -2223,6 +2547,11 @@
int CHsmsPassive::requestEventReportSend_Port_Load_Ready()
{
return requestEventReportSend("Port_Load_Ready");
+}
+
+int CHsmsPassive::requestEventReportSend_Port_Ready_To_Release()
+{
+ return requestEventReportSend("Port_Ready_To_Release");
}
int CHsmsPassive::requestEventReportSend_Port_Blocked()
@@ -2269,6 +2598,5 @@
{
return requestEventReportSend("OCR_PanelID_Read_OK");
}
-
--
Gitblit v1.9.3