From 437d3d047183eed3bbd8eb79e4b40c4a1e0427c9 Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期四, 15 一月 2026 10:39:31 +0800
Subject: [PATCH] 1.修复: CEID 校验恒通过:ceidDefined 返回 true,PauseEvent ID 不做有效性检查。Host 若下发无效 CEID,将被接受但运行时无法触发暂停,风险难以察觉。 指定事件发生时暂停;

---
 SourceCode/Bond/Servo/Model.cpp |   67 +++++++++++++++++++++++++++------
 1 files changed, 55 insertions(+), 12 deletions(-)

diff --git a/SourceCode/Bond/Servo/Model.cpp b/SourceCode/Bond/Servo/Model.cpp
index 5087821..3bc322e 100644
--- a/SourceCode/Bond/Servo/Model.cpp
+++ b/SourceCode/Bond/Servo/Model.cpp
@@ -10,6 +10,7 @@
 #include "RecipeManager.h"
 #include "GlassLogDb.h"
 #include "CParam.h"
+#include "CJobDataS.h"
 #include <algorithm>
 #include <iomanip>
 #include <sstream>
@@ -167,18 +168,6 @@
 			setControlState(ControlState::OnlineRemote);
 		}
 	};
-	listener.onEQConstantRequest = [&](void* pFrom, std::vector<EQConstant>& eqcs) -> void {
-		// 鍦ㄦ濉厖甯搁噺鍊硷紝鐩墠浠呮槸鍔�1鍚庤繑鍥�
-		for (auto& item : eqcs) {
-			sprintf_s(item.szValue, EQCONSTANT_VALUE_MAX, "Test%d", item.id + 1);
-		}
-	};
-	listener.onEQConstantSend = [&](void* pFrom, std::vector<EQConstant>& eqcs) -> void {
-		// 鍦ㄦ淇濆瓨鍜岃缃満鍣ㄥ父閲忓��
-		for (auto& item : eqcs) {
-			LOGI("onEQConstantRequest: %d, %s", item.id, item.szValue);
-		}
-	};
 	listener.onDatetimeSync = [&](void* pFrom, SYSTEMTIME& time) -> void {
 		LOGI("onDatetimeSync: %d%02d%02d%02d%02d%02d", time.wYear,
 			time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);
@@ -244,6 +233,11 @@
 				// 鐪熸鐨勨�滃紑濮嬧�濈敱 ProceedWithSlotMap 鍐崇瓥瑙﹀彂銆�
 				// 浠呭綋鏈紑鍚� CompareMapsBeforeProceeding 鏃讹紝鎵嶆部鐢ㄦ棫閫昏緫鐩存帴 Start銆�
 				LOGI("<CModel>ProceedWithCarrier");
+				if (m_master.getControlJob() == nullptr || m_master.isProcessJobsEmpty()) {
+					strErrorTxt = "rejected - ControlJob/ProcessJob not ready";
+					LOGW("<CModel>ProceedWithCarrier rejected: no CJ/PJ, port=%d", portIndex + 1);
+					return CAACK_5;
+				}
 				if (pLoadPort == nullptr || !pLoadPort->isCompareMapsBeforeProceeding()) {
 					m_master.proceedWithCarrier(portIndex);
 				}
@@ -310,6 +304,10 @@
 	CString strVarialbleFile;
 	strVarialbleFile.Format(_T("%s\\VariableList.txt"), (LPTSTR)(LPCTSTR)m_strWorkDir);
 	m_hsmsPassive.loadVarialbles((LPTSTR)(LPCTSTR)strVarialbleFile);
+	strVarialbleFile.Format(_T("%s\\DataVariableList.txt"), (LPTSTR)(LPCTSTR)m_strWorkDir);
+	m_hsmsPassive.loadDataVarialbles((LPTSTR)(LPCTSTR)strVarialbleFile);
+	strVarialbleFile.Format(_T("%s\\EquipmentConstantList.txt"), (LPTSTR)(LPCTSTR)m_strWorkDir);
+	m_hsmsPassive.loadEquipmentConstants((LPTSTR)(LPCTSTR)strVarialbleFile);
 	setControlState(m_currentControlState);
 	refreshDerivedSVs();
 	m_hsmsPassive.init(this, "APP", 7000);
@@ -317,6 +315,15 @@
 	m_hsmsPassive.loadReports((LPTSTR)(LPCTSTR)strVarialbleFile);
 	strVarialbleFile.Format(_T("%s\\CollectionEventList.txt"), (LPTSTR)(LPCTSTR)m_strWorkDir);
 	m_hsmsPassive.loadCollectionEvents((LPTSTR)(LPCTSTR)strVarialbleFile);
+	{
+		auto events = m_hsmsPassive.getCollectionEvents();
+		std::vector<unsigned int> ceids;
+		ceids.reserve(events.size());
+		for (auto e : events) {
+			if (e != nullptr) ceids.push_back(e->getEventId());
+		}
+		m_master.setAllowedCeids(ceids);
+	}
 	strVarialbleFile.Format(_T("%s\\HsmsPassive.cache"), (LPTSTR)(LPCTSTR)m_strWorkDir);
 	m_hsmsPassive.loadCacheFromFile(strVarialbleFile);
 
@@ -510,6 +517,42 @@
 		notifyPtrAndInt(RX_CODE_EQ_ROBOT_TASK, pTask, nullptr, code);
 
 	};
+	masterListener.onJobReceived = [&](void* pMaster, SERVO::CEquipment* pEquipment, int port, SERVO::CJobDataS* pJobDataS) {
+		(void)pMaster;
+		(void)port;
+		if (pEquipment == nullptr || pJobDataS == nullptr) return;
+		const int eqId = pEquipment->getID();
+		const int recipeId = pJobDataS->getMasterRecipe();
+		std::string recipe = RecipeManager::getInstance().getPPIDById(recipeId);
+		if (recipe.empty()) {
+			recipe = std::to_string(recipeId);
+		}
+		const std::string prev = pEquipment->getCurrentRecipe();
+		if (recipe.empty() || recipe == prev) {
+			pEquipment->setCurrentRecipe(recipe);
+			return;
+		}
+		pEquipment->setCurrentRecipe(recipe);
+		m_hsmsPassive.withVariableLock([&] {
+			m_hsmsPassive.setVariableValue("Clock", CToolUnits::getCurrentTimeString().c_str());
+			m_hsmsPassive.setVariableValue("EQPPExecName", recipe.c_str());
+			m_hsmsPassive.setVariableValue("SubEqpName", pEquipment->getName().c_str());
+			const char* recipeVid = nullptr;
+			switch (eqId) {
+			case EQ_ID_Bonder1: recipeVid = "Bonder1CurrentRecipe"; break;
+			case EQ_ID_Bonder2: recipeVid = "Bonder2CurrentRecipe"; break;
+			case EQ_ID_VACUUMBAKE: recipeVid = "VacuumBakeCurrentRecipe"; break;
+			case EQ_ID_BAKE_COOLING: recipeVid = "BakeCoolingCurrentRecipe"; break;
+			case EQ_ID_MEASUREMENT: recipeVid = "MeasurementCurrentRecipe"; break;
+			case EQ_ID_EFEM: recipeVid = "EFEMCurrentRecipe"; break;
+			default: break;
+			}
+			if (recipeVid != nullptr) {
+				m_hsmsPassive.setVariableValue(recipeVid, recipe.c_str());
+			}
+			m_hsmsPassive.requestEventReportSend("RecipeChanged");
+		});
+	};
 	masterListener.onLoadPortStatusChanged = [&] (void* pMaster, SERVO::CEquipment* pEquipment, short status, __int64 data) {
 		LOGE("<CModel>onLoadPortStatusChanged. status = %d", status);
 		static std::map<int, short> s_prevPortStatus;

--
Gitblit v1.9.3