From ded981a2ac5dbb456bafce5468d7289bc45e313b Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期六, 10 一月 2026 21:07:48 +0800
Subject: [PATCH] 1.S7F5查询PPID

---
 SourceCode/Bond/Servo/HsmsPassive.cpp |  323 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 301 insertions(+), 22 deletions(-)

diff --git a/SourceCode/Bond/Servo/HsmsPassive.cpp b/SourceCode/Bond/Servo/HsmsPassive.cpp
index 6208112..301cf6a 100644
--- a/SourceCode/Bond/Servo/HsmsPassive.cpp
+++ b/SourceCode/Bond/Servo/HsmsPassive.cpp
@@ -3,6 +3,7 @@
 #include "Log.h"
 #include "Model.h"
 #include "Common.h"
+#include "RecipeManager.h"
 #include <time.h>
 #include <iostream>  
 #include <time.h>  
@@ -11,6 +12,7 @@
 #include <algorithm>
 #include <set>
 #include <regex>
+#include <sstream>
 
 // ControlState values (keep in sync with Model::ControlState / VariableList.txt)
 static constexpr uint8_t kControlStateOnlineRemote = 5;
@@ -19,6 +21,19 @@
 const char ACK[2] = {0, 1};
 const char* ACK0 = &ACK[0];
 const char* ACK1 = &ACK[1];
+
+// Log SECS-II message briefly to avoid huge strings causing issues.
+static void LogSecsMessageBrief(const char* tag, IMessage* pMessage, size_t maxLen = 1024)
+{
+	if (pMessage == nullptr) return;
+	const char* msgStr = pMessage->toString();
+	if (msgStr == nullptr) return;
+	std::string buf(msgStr);
+	if (buf.size() > maxLen) {
+		buf = buf.substr(0, maxLen) + "...<truncated>";
+	}
+	LOGI("%s%s", tag, buf.c_str());
+}
 
 unsigned __stdcall CimWorkThreadFunction(LPVOID lpParam)
 {
@@ -525,26 +540,37 @@
 
 void CHsmsPassive::setVariableValue(const char* pszName, __int64 value)
 {
-	auto v = getVariable(pszName);
-	if (v != nullptr) {
+	// Protect variable list updates; multiple threads may set SVs.
+	Lock();
+	if (auto v = getVariable(pszName)) {
 		v->setValue(value);
 	}
+	Unlock();
 }
 
 void CHsmsPassive::setVariableValue(const char* pszName, const char* value)
 {
-	auto v = getVariable(pszName);
-	if (v != nullptr) {
+	Lock();
+	if (auto v = getVariable(pszName)) {
 		v->setValue(value);
 	}
+	Unlock();
 }
 
 void CHsmsPassive::setVariableValue(const char* pszName, std::vector<SERVO::CVariable>& vars)
 {
-	auto v = getVariable(pszName);
-	if (v != nullptr) {
+	Lock();
+	if (auto v = getVariable(pszName)) {
 		v->setValue(vars);
 	}
+	Unlock();
+}
+
+void CHsmsPassive::withVariableLock(const std::function<void()>& fn)
+{
+	Lock();
+	if (fn) fn();
+	Unlock();
 }
 
 static bool isValidFormat(const std::string& fmt)
@@ -563,8 +589,8 @@
 	Lock();
 	int maxId = 0;
 	for (auto v : m_variabels) {
-		if (v != nullptr && v->getVarialbleId() > maxId) {
-			maxId = v->getVarialbleId();
+		if (v != nullptr && static_cast<int>(v->getVarialbleId()) > maxId) {
+			maxId = static_cast<int>(v->getVarialbleId());
 		}
 	}
 	outId = maxId + 1;
@@ -1287,13 +1313,19 @@
 		HEADER* pHeader = pMessage->getHeader();
 		int nStream = (pHeader->stream & 0x7F);
 
-		LOGI("<HSMS>[Received]%s", pMessage->toString());
+		LogSecsMessageBrief("<HSMS>[Received]", pMessage);
 		if (nStream == 1 && pHeader->function == 1) {
 			// S1F1
 			replyAreYouThere(pMessage);
 		}
 		else if (nStream == 1 && pHeader->function == 3) {
 			replySelectedEquipmentStatusData(pMessage);
+		}
+		else if (nStream == 1 && pHeader->function == 11) {
+			replyStatusVariableNamelistRequest(pMessage);
+		}
+		else if (nStream == 1 && pHeader->function == 23) {
+			replyCollectionEventNamelistRequest(pMessage);
 		}
 		else if (nStream == 1 && pHeader->function == 13) {
 			replyEstablishCommunications(pMessage);
@@ -1340,6 +1372,12 @@
 		else if (nStream == 7 && pHeader->function == 19) {
 			replyQueryPPIDList(pMessage);
 		}
+		else if (nStream == 7 && pHeader->function == 17) {
+			replyDeletePPID(pMessage);
+		}
+		else if (nStream == 7 && pHeader->function == 5) {
+			replyProcessProgramRequest(pMessage);
+		}
 		else if (nStream == 10 && pHeader->function == 3) {
 			replyTerminalDisplay(pMessage);
 		}
@@ -1379,7 +1417,12 @@
 		return -1;
 	}
 
-	int nBufSize = file.GetLength();
+	ULONGLONG len = file.GetLength();
+	if (len > INT_MAX) {
+		file.Close();
+		return -1;
+	}
+	int nBufSize = static_cast<int>(len);
 	char* pszBuffer = new char[nBufSize];
 	file.Read(pszBuffer, nBufSize);
 	file.Close();
@@ -1621,7 +1664,7 @@
 				ASSERT(pMessage);
 				m_pPassive->sendMessage(pMessage);
 				LOGI("<HSMS>[SEND]SysByte=%u sessionId:%d", pMessage->getHeader()->systemBytes, pMessage->getHeader()->sessionId);
-				LOGI("<HSMS>[SEND]%s", pMessage->toString());
+				LogSecsMessageBrief("<HSMS>[SEND]", pMessage);
 
 				int nRet = WaitForSingleObject(pAction->getEvent(), pAction->getTimeout() * 1000);
 				if (nRet == WAIT_TIMEOUT) {
@@ -1647,7 +1690,7 @@
 				ASSERT(pMessage);
 				m_pPassive->sendMessage(pMessage);
 				LOGI("<HSMS>[SEND]SysByte=%u sessionId:%d", pMessage->getHeader()->systemBytes, pMessage->getHeader()->sessionId);
-				LOGI("<HSMS>[SEND]%s", pMessage->toString());
+				LogSecsMessageBrief("<HSMS>[SEND]", pMessage);
 
 			}
 		}
@@ -1671,7 +1714,7 @@
 	m_pPassive->sendMessage(pMessage);
 	LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d",
 		pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes);
-	LOGI("<HSMS>[SEND]%s", pMessage->toString());
+	LogSecsMessageBrief("<HSMS>[SEND]", pMessage);
 	HSMS_Destroy1Message(pMessage);
 }
 
@@ -1714,7 +1757,7 @@
 	m_pPassive->sendMessage(pMessage);
 	LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d",
 		pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes);
-	LOGI("<HSMS>[SEND]%s", pMessage->toString());
+	LogSecsMessageBrief("<HSMS>[SEND]", pMessage);
 	HSMS_Destroy1Message(pMessage);
 
 	return 0;
@@ -1777,7 +1820,7 @@
 	m_pPassive->sendMessage(pMessage);
 	LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d",
 		pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes);
-	LOGI("<HSMS>[SEND]%s", pMessage->toString());
+	LogSecsMessageBrief("<HSMS>[SEND]", pMessage);
 	HSMS_Destroy1Message(pMessage);
 
 	return 0;
@@ -1824,12 +1867,168 @@
 	m_pPassive->sendMessage(pMessage);
 	LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d",
 		pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes);
-	LOGI("<HSMS>[SEND]%s", pMessage->toString());
+	LogSecsMessageBrief("<HSMS>[SEND]", pMessage);
 	HSMS_Destroy1Message(pMessage);
 
 
 
 	return 0;
+}
+
+// S1F11
+int CHsmsPassive::replyStatusVariableNamelistRequest(IMessage* pRecv)
+{
+	if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
+		return ER_NOTSELECT;
+	}
+
+	std::vector<unsigned short> reqIds;
+	ISECS2Item* pBody = pRecv->getBody();
+	if (pBody != nullptr && pBody->getType() == SITYPE::L) {
+		const int sz = pBody->getSubItemSize();
+		for (int i = 0; i < sz; ++i) {
+			unsigned short id = 0;
+			if (pBody->getSubItemU2(i, id)) {
+				reqIds.push_back(id);
+			}
+		}
+	}
+
+	// Build response list items: {L:3 SVID, SVNAME, UNITS}
+	std::vector<unsigned short> svids;
+	std::set<unsigned short> requested(reqIds.begin(), reqIds.end());
+	Lock();
+	if (reqIds.empty()) {
+		for (auto v : m_variabels) {
+			svids.push_back(static_cast<unsigned short>(v->getVarialbleId()));
+		}
+	}
+	else {
+		// include requested IDs (existing + unknown marker)
+		for (auto id : requested) {
+			svids.push_back(id);
+		}
+	}
+	Unlock();
+
+	IMessage* pMessage = NULL;
+	HSMS_Create1Message(pMessage, m_nSessionId, 1, 12, pRecv->getHeader()->systemBytes);
+	ASSERT(pMessage);
+
+	ISECS2Item* pList = pMessage->getBody(); // Body is L[n] of {SVID, SVNAME, UNITS}
+	for (auto id : svids) {
+		ISECS2Item* pEntry = pList->addItem();
+		pEntry->addU2Item(id, "SVID");
+		SERVO::CVariable* v = getVariable((int)id);
+		if (v != nullptr) {
+			pEntry->addItem(v->getName().c_str(), "SVNAME");
+			// Use remark as UNITS if provided; empty string if none.
+			pEntry->addItem(v->getRemark().c_str(), "UNITS");
+		}
+		else {
+			// Unknown SVID: A:0 for name/units
+			pEntry->addItem("", "SVNAME");
+			pEntry->addItem("", "UNITS");
+		}
+	}
+
+	m_pPassive->sendMessage(pMessage);
+	LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d",
+		pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes);
+	LogSecsMessageBrief("<HSMS>[SEND]", pMessage);
+	HSMS_Destroy1Message(pMessage);
+
+	return ER_NOERROR;
+}
+
+// S1F23
+int CHsmsPassive::replyCollectionEventNamelistRequest(IMessage* pRecv)
+{
+	if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
+		return ER_NOTSELECT;
+	}
+
+	std::vector<unsigned short> reqIds;
+	ISECS2Item* pBody = pRecv->getBody();
+	if (pBody != nullptr && pBody->getType() == SITYPE::L) {
+		const int sz = pBody->getSubItemSize();
+		for (int i = 0; i < sz; ++i) {
+			unsigned short id = 0;
+			if (pBody->getSubItemU2(i, id)) {
+				reqIds.push_back(id);
+			}
+		}
+	}
+
+	struct CEInfo {
+		unsigned short id{ 0 };
+		std::string name;
+		std::vector<unsigned short> vids;
+	};
+	std::vector<CEInfo> ceInfos;
+	{
+		Lock();
+		if (reqIds.empty()) {
+			for (auto e : m_collectionEvents) {
+				if (e == nullptr) continue;
+				CEInfo info;
+				info.id = static_cast<unsigned short>(e->getEventId());
+				info.name = e->getName();
+				std::set<unsigned short> vidSet;
+				for (auto rpt : e->getReports()) {
+					if (rpt == nullptr) continue;
+					for (auto vid : rpt->getVids()) {
+						vidSet.insert(static_cast<unsigned short>(vid));
+					}
+				}
+				info.vids.assign(vidSet.begin(), vidSet.end());
+				ceInfos.push_back(std::move(info));
+			}
+		}
+		else {
+			for (auto id : reqIds) {
+				CEInfo info;
+				info.id = id;
+				SERVO::CCollectionEvent* e = getEvent(id);
+				if (e != nullptr) {
+					info.name = e->getName();
+					std::set<unsigned short> vidSet;
+					for (auto rpt : e->getReports()) {
+						if (rpt == nullptr) continue;
+						for (auto vid : rpt->getVids()) {
+							vidSet.insert(static_cast<unsigned short>(vid));
+						}
+					}
+					info.vids.assign(vidSet.begin(), vidSet.end());
+				}
+				ceInfos.push_back(std::move(info));
+			}
+		}
+		Unlock();
+	}
+
+	IMessage* pMessage = NULL;
+	HSMS_Create1Message(pMessage, m_nSessionId, 1, 24, pRecv->getHeader()->systemBytes);
+	ASSERT(pMessage);
+
+	ISECS2Item* pList = pMessage->getBody(); // Body is L[n] of {CEID, CENAME, L[VIDs]}
+	for (const auto& info : ceInfos) {
+		ISECS2Item* pEntry = pList->addItem();
+		pEntry->addU2Item(info.id, "CEID");
+		pEntry->addItem(info.name.c_str(), "CENAME"); // empty if unknown
+		ISECS2Item* pVidList = pEntry->addItem();
+		for (auto vid : info.vids) {
+			pVidList->addU2Item(vid, "VID");
+		}
+	}
+
+	m_pPassive->sendMessage(pMessage);
+	LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d",
+		pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes);
+	LogSecsMessageBrief("<HSMS>[SEND]", pMessage);
+	HSMS_Destroy1Message(pMessage);
+
+	return ER_NOERROR;
 }
 
 // S2F13
@@ -1875,7 +2074,7 @@
 	m_pPassive->sendMessage(pMessage);
 	LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d",
 		pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes);
-	LOGI("<HSMS>[SEND]%s", pMessage->toString());
+	LogSecsMessageBrief("<HSMS>[SEND]", pMessage);
 	HSMS_Destroy1Message(pMessage);
 
 	return 0;
@@ -2276,7 +2475,7 @@
 	m_pPassive->sendMessage(pMessage);
 	LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d",
 		pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes);
-	LOGI("<HSMS>[SEND]%s", pMessage->toString());
+	LogSecsMessageBrief("<HSMS>[SEND]", pMessage);
 	HSMS_Destroy1Message(pMessage);
 	
 	return 0;
@@ -2358,6 +2557,86 @@
 	return 0;
 }
 
+// S7F17 Delete Process Program (PPID list) / S7F18
+int CHsmsPassive::replyDeletePPID(IMessage* pRecv)
+{
+	if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
+		return ER_NOTSELECT;
+	}
+
+	bool allOk = true;
+	const bool deleteAll = (pRecv->getBody() == nullptr || pRecv->getBody()->getSubItemSize() == 0);
+	std::vector<std::string> ppids;
+	ISECS2Item* pBody = pRecv->getBody();
+	const int nCount = pBody ? pBody->getSubItemSize() : 0;
+	for (int i = 0; i < nCount; ++i) {
+		const char* pszPPID = nullptr;
+		if (pBody->getSubItemString(i, pszPPID) && pszPPID != nullptr) {
+			ppids.emplace_back(pszPPID);
+		}
+		else {
+			allOk = false;
+		}
+	}
+
+	if (deleteAll || !ppids.empty()) {
+		if (m_listener.onDeletePPID != nullptr) {
+			allOk = m_listener.onDeletePPID(this, ppids);
+		}
+		else {
+			// no handler provided; treat as failure
+			allOk = false;
+			LOGW("<HSMS>DeletePPID request ignored: no onDeletePPID listener");
+		}
+	}
+
+
+	replyAck(7, 18, pRecv->getHeader()->systemBytes, allOk ? BYTE(0) : BYTE(1), "ACKC7");
+	return 0;
+}
+
+// S7F5 Process Program Request -> reply S7F6 with PPID + PPBODY
+int CHsmsPassive::replyProcessProgramRequest(IMessage* pRecv)
+{
+	if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
+		return ER_NOTSELECT;
+	}
+	ISECS2Item* pBody = pRecv->getBody();
+	const char* pszPPID = nullptr;
+	if (pBody == nullptr || !pBody->getString(pszPPID) || pszPPID == nullptr) {
+		return ER_PARAM_ERROR;
+	}
+	std::string ppid(pszPPID);
+	std::string ppbody;
+	// 绠�鍗曡仛鍚堬細浠� RecipeManager 鍙栬澶囬厤鏂癸紝鎷兼垚鏂囨湰
+	auto recipeInfo = RecipeManager::getInstance().getRecipeByPPID(ppid);
+	if (!recipeInfo.strPPID.empty()) {
+		for (const auto& dev : recipeInfo.vecDeviceList) {
+			if (!ppbody.empty()) ppbody.append("\n");
+			ppbody.append(dev.strDeviceName);
+			ppbody.append(",");
+			ppbody.append(std::to_string(dev.nRecipeID));
+			ppbody.append(",");
+			ppbody.append(dev.strRecipeName);
+			// 闄勫姞鍙傛暟澶у皬淇℃伅锛堢洰鍓嶇己灏戝叿浣撳弬鏁板垪琛級
+			ppbody.append(",paramsSize=");
+			ppbody.append(std::to_string(dev.paramsRawData.size()));
+		}
+	}
+
+	IMessage* pMessage = nullptr;
+	if (HSMS_Create1Message(pMessage, m_nSessionId, 7, 6, pRecv->getHeader()->systemBytes) != 0 || pMessage == nullptr) {
+		return ER_CREATED_MESSAGE;
+	}
+	ISECS2Item* pRspBody = pMessage->getBody(); // top-level L:2
+	pRspBody->addItem(ppid.c_str(), "PPID");
+	pRspBody->addItem(ppbody.c_str(), "PPBODY");
+	m_pPassive->sendMessage(pMessage);
+	LogSecsMessageBrief("<HSMS>[SEND]", pMessage);
+	HSMS_Destroy1Message(pMessage);
+	return 0;
+}
+
 // S7F19
 int CHsmsPassive::replyQueryPPIDList(IMessage* pRecv)
 {
@@ -2381,7 +2660,7 @@
 	m_pPassive->sendMessage(pMessage);
 	LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d",
 		pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes);
-	LOGI("<HSMS>[SEND]%s", pMessage->toString());
+	LogSecsMessageBrief("<HSMS>[SEND]", pMessage);
 	HSMS_Destroy1Message(pMessage);
 
 	return 0;
@@ -2554,7 +2833,7 @@
 	m_pPassive->sendMessage(pReply);
 	LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d",
 		pReply->getHeader()->sessionId, pReply->getHeader()->sType, pReply->getHeader()->systemBytes);
-	LOGI("<HSMS>[SEND]%s", pReply->toString());
+	LogSecsMessageBrief("<HSMS>[SEND]", pReply);
 	HSMS_Destroy1Message(pReply);
 
 
@@ -2584,7 +2863,7 @@
 		m_pPassive->sendMessage(pMessage);
 		LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d",
 			pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes);
-		LOGI("<HSMS>[SEND]%s", pMessage->toString());
+		LogSecsMessageBrief("<HSMS>[SEND]", pMessage);
 		HSMS_Destroy1Message(pMessage);
 		return 0;
 	}
@@ -2671,7 +2950,7 @@
 	m_pPassive->sendMessage(pMessage);
 	LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d",
 		pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes);
-	LOGI("<HSMS>[SEND]%s", pMessage->toString());
+	LogSecsMessageBrief("<HSMS>[SEND]", pMessage);
 	HSMS_Destroy1Message(pMessage);
 
 

--
Gitblit v1.9.3