From 9c9100b078e9ac4ee7ed61500b4d7c7a74207549 Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期四, 08 一月 2026 10:32:44 +0800
Subject: [PATCH] 1.继续完善模拟测试等

---
 SourceCode/Bond/EAPSimulator/CHsmsActive.cpp     |   48 ++++++++++++++-
 SourceCode/Bond/EAPSimulator/Resource.h          |    3 
 SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp |   34 +++++++++++
 SourceCode/Bond/EAPSimulator/CPJsDlg.cpp         |    2 
 SourceCode/Bond/EAPSimulator/CHsmsActive.h       |   22 ++++--
 SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h   |    1 
 SourceCode/Bond/Servo/HsmsPassive.cpp            |    7 +-
 SourceCode/Bond/EAPSimulator/EAPSimulator.rc     |    0 
 SourceCode/Bond/Servo/CMaster.cpp                |    7 +
 SourceCode/Bond/Servo/Model.cpp                  |    8 ++
 SourceCode/Bond/Servo/CLoadPort.cpp              |    4 
 11 files changed, 112 insertions(+), 24 deletions(-)

diff --git a/SourceCode/Bond/EAPSimulator/CHsmsActive.cpp b/SourceCode/Bond/EAPSimulator/CHsmsActive.cpp
index b334708..5b98173 100644
--- a/SourceCode/Bond/EAPSimulator/CHsmsActive.cpp
+++ b/SourceCode/Bond/EAPSimulator/CHsmsActive.cpp
@@ -1,9 +1,9 @@
-#include "pch.h"
+锘�#include "pch.h"
 #include "CHsmsActive.h"
 #include "Log.h"
 
 
-static unsigned int DATAID = 1;
+static unsigned short DATAID = 1;
 
 CHsmsActive::CHsmsActive()
 {
@@ -64,7 +64,7 @@
 		HEADER* pHeader = pMessage->getHeader();
 		int nStream = (pHeader->stream & 0x7F);
 
-		TRACE("收到消息 S%dF%d================\n", pHeader->stream & 0x7F, pHeader->function);
+		TRACE("鏀跺埌娑堟伅 S%dF%d================\n", pHeader->stream & 0x7F, pHeader->function);
 		TRACE("Body:%s\n", pMessage->toString());
 		LOGI("onRecvDataMessage(%s).", pMessage->toString());
 
@@ -349,12 +349,50 @@
 	return hsmsCarrierActionRequest(DATAID, "CarrierRelease", pszCarrierId, PTN);
 }
 
+int CHsmsActive::hsmsProceedWithSlotMap(unsigned int DATAID,
+	const char* pszCarrierId,
+	unsigned char PTN,
+	const char* pszLotId,
+	const std::vector<std::string>& panelIds,
+	const std::vector<unsigned char>& slotMap)
+{
+	IMessage* pMessage = nullptr;
+	int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 3 | REPLY, 17, ++m_nSystemByte);
+	if (nRet != 0 || pMessage == nullptr) {
+		return nRet;
+	}
+
+	pMessage->getBody()->addU4Item(DATAID, "DATAID");
+	pMessage->getBody()->addItem("ProceedWithSlotMap", "CARRIERACTION");
+	pMessage->getBody()->addItem(pszCarrierId, "CARRIERID");
+	pMessage->getBody()->addU1Item(PTN, "PTN");
+
+	// Extended params (currently not parsed by Servo side): { LOTID, PANELID_LIST, SLOTMAP_LIST }
+	ISECS2Item* pParams = pMessage->getBody()->addItem(); // L
+	pParams->addItem(pszLotId != nullptr ? pszLotId : "", "LOTID");
+
+	ISECS2Item* pPanelList = pParams->addItem(); // L
+	for (const auto& id : panelIds) {
+		pPanelList->addItem(id.c_str(), "PANELID");
+	}
+
+	ISECS2Item* pSlotMapList = pParams->addItem(); // L
+	for (auto v : slotMap) {
+		pSlotMapList->addU1Item(v, "SLOTSTATE");
+	}
+
+	m_pActive->sendMessage(pMessage);
+	HSMS_Destroy1Message(pMessage);
+
+	return 0;
+}
+
 int CHsmsActive::hsmsPRJobMultiCreate(std::vector<SERVO::CProcessJob*>& pjs)
 {
 	IMessage* pMessage = nullptr;
 	int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 16 | REPLY, 15, ++m_nSystemByte);
 	char szMF[32] = {14};
-	pMessage->getBody()->addU4Item(++DATAID, "DATAID");
+	pMessage->getBody()->addU2Item(++DATAID, "DATAID");
 	auto itemPjs = pMessage->getBody()->addItem();
 	for (auto pj : pjs) {
 		auto itemPj = itemPjs->addItem();
@@ -434,7 +472,7 @@
 	return 0;
 }
 
-// 通用的reply ack函数
+// 閫氱敤鐨剅eply ack鍑芥暟
 void CHsmsActive::replyAck(int s, int f, unsigned int systemBytes, BYTE ack, const char* pszAckName)
 {
 	IMessage* pMessage = NULL;
diff --git a/SourceCode/Bond/EAPSimulator/CHsmsActive.h b/SourceCode/Bond/EAPSimulator/CHsmsActive.h
index 29abeb5..04bb2c1 100644
--- a/SourceCode/Bond/EAPSimulator/CHsmsActive.h
+++ b/SourceCode/Bond/EAPSimulator/CHsmsActive.h
@@ -1,4 +1,4 @@
-#pragma once
+锘�#pragma once
 #include <string>
 #include <vector>
 #include <map>
@@ -36,7 +36,7 @@
 	// Deselect Request
 	int hsmsDeselectRequest();
 
-	// 建立通讯(S1F13)
+	// 寤虹珛閫氳(S1F13)
 	int hsmsEstablishCommunications();
 
 	// Are You There
@@ -63,18 +63,18 @@
 	// Configure Spooling
 	int hsmsConfigureSpooling(std::map<unsigned int, std::set<unsigned int>>& spoolingConfig);
 
-	// 发送或清空缓存的消息
+	// 鍙戦�佹垨娓呯┖缂撳瓨鐨勬秷鎭�
 	int hsmsTransmitSpooledData();
 	int hsmsPurgeSpooledData();
 
-	// 查询变量
+	// 鏌ヨ鍙橀噺
 	int hsmsSelectedEquipmentStatusRequest(unsigned int SVID);
 
-	// 查询PPID List
+	// 鏌ヨPPID List
 	int hsmsQueryPPIDList();
 
 	// S3F17
-	// 卡匣动作请求
+	// 鍗″專鍔ㄤ綔璇锋眰
 	int hsmsCarrierActionRequest(unsigned int DATAID, 
 		const char* pszCarrierAction,
 		const char* pszCarrierId,
@@ -82,7 +82,13 @@
 	int hsmsProceedWithCarrier(unsigned int DATAID,
 		const char* pszCarrierId,
 		unsigned char PTN);
-	int CHsmsActive::hsmsCarrierRelease(unsigned int DATAID,
+	int hsmsProceedWithSlotMap(unsigned int DATAID,
+		const char* pszCarrierId,
+		unsigned char PTN,
+		const char* pszLotId,
+		const std::vector<std::string>& panelIds,
+		const std::vector<unsigned char>& slotMap);
+	int hsmsCarrierRelease(unsigned int DATAID,
 		const char* pszCarrierId,
 		unsigned char PTN);
 
@@ -92,7 +98,7 @@
 	// S14F9
 	int hsmsCreateControlJob(const char* pszControlJobId, std::vector<std::string>& processJobIds);
 
-	// 通过的reply函数
+	// 閫氳繃鐨剅eply鍑芥暟
 	void replyAck(int s, int f, unsigned int systemBytes, BYTE ack, const char* pszAckName);
 
 	// reply ack0
diff --git a/SourceCode/Bond/EAPSimulator/CPJsDlg.cpp b/SourceCode/Bond/EAPSimulator/CPJsDlg.cpp
index 212291f..9f1c61b 100644
--- a/SourceCode/Bond/EAPSimulator/CPJsDlg.cpp
+++ b/SourceCode/Bond/EAPSimulator/CPJsDlg.cpp
@@ -98,7 +98,7 @@
 	{
 		SERVO::CProcessJob* pj = new SERVO::CProcessJob("PJ0001");
 		std::vector<uint8_t> slots1{ 1, 2, 3 };
-		pj->addCarrier("CID1001", slots1);
+		pj->addCarrier("Test-Cassette-001", slots1);
 		pj->setRecipe(SERVO::RecipeMethod::NoTuning, "P1001");
 		m_pjs.push_back(pj);
 	}
diff --git a/SourceCode/Bond/EAPSimulator/EAPSimulator.rc b/SourceCode/Bond/EAPSimulator/EAPSimulator.rc
index 53eb764..b153a48 100644
--- a/SourceCode/Bond/EAPSimulator/EAPSimulator.rc
+++ b/SourceCode/Bond/EAPSimulator/EAPSimulator.rc
Binary files differ
diff --git a/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp b/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp
index e15ff68..9e0a4de 100644
--- a/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp
+++ b/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp
@@ -9,6 +9,8 @@
 #include "afxdialogex.h"
 #include "Common.h"
 #include <regex>
+#include <string>
+#include <vector>
 #include "CTerminalDisplayDlg.h"
 #include "CEDEventReportDlg.h"
 #include "CDefineReportsDlg.h"
@@ -90,6 +92,7 @@
 	ON_BN_CLICKED(IDC_BUTTON_PURGE_SPOOLED_DATA, &CEAPSimulatorDlg::OnBnClickedButtonPurgeSpooledData)
 	ON_BN_CLICKED(IDC_BUTTON_QUERY_PPID_LIST, &CEAPSimulatorDlg::OnBnClickedButtonQueryPpidList)
 	ON_BN_CLICKED(IDC_BUTTON_PROCEED_WITH_CARRIER, &CEAPSimulatorDlg::OnBnClickedButtonProceedWithCarrier)
+	ON_BN_CLICKED(IDC_BUTTON_PROCEED_WITH_SLOTMAP, &CEAPSimulatorDlg::OnBnClickedButtonProceedWithSlotMap)
 	ON_BN_CLICKED(IDC_BUTTON_CARRIER_RELEASE, &CEAPSimulatorDlg::OnBnClickedButtonCarrierRelease)
 	ON_BN_CLICKED(IDC_BUTTON_QUERY_CJ_SPACE, &CEAPSimulatorDlg::OnBnClickedButtonQueryCjSpace)
 	ON_BN_CLICKED(IDC_BUTTON_QUERY_PJ_SPACE, &CEAPSimulatorDlg::OnBnClickedButtonQueryPjSpace)
@@ -177,6 +180,19 @@
 	//  鎵ц姝ゆ搷浣�
 	SetIcon(m_hIcon, TRUE);			// 璁剧疆澶у浘鏍�
 	SetIcon(m_hIcon, FALSE);		// 璁剧疆灏忓浘鏍�
+
+	// Add missing test button at runtime (resource file is UTF-16, keep it unchanged)
+	{
+		CRect rc(126, 120, 126 + 108, 120 + 14); // dialog units
+		MapDialogRect(&rc);
+		HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S3F17_ProceedWithSlotMap"),
+			WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+			rc.left, rc.top, rc.Width(), rc.Height(),
+			m_hWnd, (HMENU)IDC_BUTTON_PROCEED_WITH_SLOTMAP, AfxGetInstanceHandle(), nullptr);
+		if (hBtn != nullptr) {
+			::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE);
+		}
+	}
 
 	SetDlgItemText(IDC_EDIT_IP, _T("127.0.0.1"));
 	SetDlgItemInt(IDC_EDIT_PORT, 7000);
@@ -283,6 +299,9 @@
 	GetDlgItem(IDC_BUTTON_PURGE_SPOOLED_DATA)->EnableWindow(enabled);
 	GetDlgItem(IDC_BUTTON_QUERY_PPID_LIST)->EnableWindow(enabled);	
 	GetDlgItem(IDC_BUTTON_PROCEED_WITH_CARRIER)->EnableWindow(enabled);	
+	if (GetDlgItem(IDC_BUTTON_PROCEED_WITH_SLOTMAP) != nullptr) {
+		GetDlgItem(IDC_BUTTON_PROCEED_WITH_SLOTMAP)->EnableWindow(enabled);
+	}
 	GetDlgItem(IDC_BUTTON_CARRIER_RELEASE)->EnableWindow(enabled);
 	GetDlgItem(IDC_BUTTON_QUERY_CJ_SPACE)->EnableWindow(enabled);
 	GetDlgItem(IDC_BUTTON_QUERY_PJ_SPACE)->EnableWindow(enabled);
@@ -406,6 +425,19 @@
 	theApp.m_model.m_pHsmsActive->hsmsProceedWithCarrier(DATAID++, "CSX 52078", 1);
 }
 
+void CEAPSimulatorDlg::OnBnClickedButtonProceedWithSlotMap()
+{
+	// Example payload (edit as needed)
+	std::vector<std::string> panelIds = {
+		"PANEL_01","PANEL_02","PANEL_03","PANEL_04",
+		"PANEL_05","PANEL_06","PANEL_07","PANEL_08"
+	};
+	std::vector<unsigned char> slotMap = {
+		3,3,1,1,1,1,1,1 // 1=Empty, 3=Exist
+	};
+	theApp.m_model.m_pHsmsActive->hsmsProceedWithSlotMap(DATAID++, "CSX 52078", 1, "LOT_0001", panelIds, slotMap);
+}
+
 void CEAPSimulatorDlg::OnBnClickedButtonCarrierRelease()
 {
 	theApp.m_model.m_pHsmsActive->hsmsCarrierRelease(DATAID++, "CSX 52078", 2);
@@ -419,6 +451,6 @@
 
 void CEAPSimulatorDlg::OnBnClickedButtonCreateCj()
 {
-	std::vector<std::string> processJobIds = {"PJ0001", "PJ0003"};
+	std::vector<std::string> processJobIds = {"PJ0001"};
 	theApp.m_model.m_pHsmsActive->hsmsCreateControlJob("CJ5007", processJobIds);
 }
diff --git a/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h b/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h
index e10cf1a..7efa6a4 100644
--- a/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h
+++ b/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h
@@ -58,6 +58,7 @@
 	afx_msg void OnBnClickedButtonPurgeSpooledData();
 	afx_msg void OnBnClickedButtonQueryPpidList();
 	afx_msg void OnBnClickedButtonProceedWithCarrier();
+	afx_msg void OnBnClickedButtonProceedWithSlotMap();
 	afx_msg void OnBnClickedButtonCarrierRelease();
 	afx_msg void OnBnClickedButtonQueryCjSpace();
 	afx_msg void OnBnClickedButtonQueryPjSpace();
diff --git a/SourceCode/Bond/EAPSimulator/Resource.h b/SourceCode/Bond/EAPSimulator/Resource.h
index 96c191e..5677b18 100644
--- a/SourceCode/Bond/EAPSimulator/Resource.h
+++ b/SourceCode/Bond/EAPSimulator/Resource.h
@@ -57,6 +57,7 @@
 #define IDC_BUTTON_CREATE_PJ2           1040
 #define IDC_BUTTON_CREATE_CJ            1040
 #define IDC_BUTTON_DELETE               1041
+#define IDC_BUTTON_PROCEED_WITH_SLOTMAP 1042
 
 // Next default values for new objects
 // 
@@ -64,7 +65,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        143
 #define _APS_NEXT_COMMAND_VALUE         32771
-#define _APS_NEXT_CONTROL_VALUE         1042
+#define _APS_NEXT_CONTROL_VALUE         1043
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
diff --git a/SourceCode/Bond/Servo/CLoadPort.cpp b/SourceCode/Bond/Servo/CLoadPort.cpp
index 175d593..0df47b8 100644
--- a/SourceCode/Bond/Servo/CLoadPort.cpp
+++ b/SourceCode/Bond/Servo/CLoadPort.cpp
@@ -364,7 +364,6 @@
 
 
 		// 妯℃嫙娴嬭瘯
-		/*
 		if (m_nIndex == 0) {
 			static int ii = 0;
 			ii++;
@@ -377,6 +376,7 @@
 				portStatusReport.setCassetteId("CID1001");
 				int nRet = portStatusReport.serialize(szBuffer, 64);
 				decodePortStatusReport(pStep, szBuffer, 64);
+				LOGI("<CLoadPort>Port1杞藉叆妯℃嫙鏁版嵁锛� id:CID1001 map: 0xf");
 			}
 		}
 		if (m_nIndex == 1) {
@@ -391,9 +391,9 @@
 				portStatusReport.setCassetteId("CID1004");
 				int nRet = portStatusReport.serialize(szBuffer, 64);
 				decodePortStatusReport(pStep, szBuffer, 64);
+				LOGI("<CLoadPort>Port2杞藉叆妯℃嫙鏁版嵁锛� id:CID1004 map: 0xff");
 			}
 		}
-		*/
 	}
 
 	void CLoadPort::serialize(CArchive& ar)
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index f27a523..0ab057f 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -2082,8 +2082,8 @@
 				static bool inited = false;
 				static SERVO::CGlass simGlass;
 				static SERVO::CVcrEventReport simVcr;
-				static SERVO::CProcessJob simPj("SIM_PJ_001");
-				static SERVO::CControlJob simCj("SIM_CJ_001");
+				static SERVO::CProcessJob simPj("PJ1001");
+				static SERVO::CControlJob simCj("CJ5007");
 
 				if (!inited) {
 					inited = true;
@@ -2814,6 +2814,9 @@
 
 
 		this->saveState();
+		if (m_listener.onControlJobChanged) {
+			m_listener.onControlJobChanged(this);
+		}
 
 		return (int)m_processJobs.size();
 	}
diff --git a/SourceCode/Bond/Servo/HsmsPassive.cpp b/SourceCode/Bond/Servo/HsmsPassive.cpp
index cd16e19..93ddb4b 100644
--- a/SourceCode/Bond/Servo/HsmsPassive.cpp
+++ b/SourceCode/Bond/Servo/HsmsPassive.cpp
@@ -2585,9 +2585,6 @@
 		pjs.push_back(pj);
 	}
 
-	ASSERT(m_listener.onPRJobMultiCreate != nullptr);
-	int nRet = m_listener.onPRJobMultiCreate(this, pjs);
-
 
 	// 鍥炲鎶ユ枃
 	IMessage* pMessage = NULL;
@@ -2622,6 +2619,10 @@
 	HSMS_Destroy1Message(pMessage);
 
 
+	ASSERT(m_listener.onPRJobMultiCreate != nullptr);
+	int nRet = m_listener.onPRJobMultiCreate(this, pjs);
+
+
 	// 閲婃斁鏈夐棶棰�(鏈坊鍔犲埌master)鐨勫唴瀛�
 	for (auto p : pjs) {
 		if(!p->issues().empty()) delete p;
diff --git a/SourceCode/Bond/Servo/Model.cpp b/SourceCode/Bond/Servo/Model.cpp
index 5857dca..bbff0f7 100644
--- a/SourceCode/Bond/Servo/Model.cpp
+++ b/SourceCode/Bond/Servo/Model.cpp
@@ -26,6 +26,9 @@
 {
 	// CJobSpace: how many ControlJobs can be created (current implementation supports 0/1).
 	m_hsmsPassive.setVariableValue("CJobSpace", (__int64)(m_master.canCreateControlJob() ? 1 : 0));
+
+	// PJobSpace: how many ProcessJobs can be created (current implementation supports 0/1).
+	m_hsmsPassive.setVariableValue("PJobSpace", (__int64)(m_master.isProcessJobsEmpty() ? 1 : 0));
 }
 
 IObservable* CModel::getObservable()
@@ -181,11 +184,13 @@
 
 			const unsigned int portIndex = PTN - 1;
 			SERVO::CLoadPort* pLoadPort = (SERVO::CLoadPort*)m_master.getEquipment(EQ_ID_LOADPORT1 + portIndex);
+			LOGI("<Model>onCarrierAction %d, %s, %d, %d", DATAID, pszCarrierAction, pszCarrierId, PTN);
 
 			if (_strcmpi(pszCarrierAction, "ProceedWithCarrier") == 0) {
 				// 鏂囨。娴佺▼锛歅roceedWithCarrier 涔嬪悗璁惧杩涘叆 Check SlotMap锛圵FH锛夛紝
 				// 鐪熸鐨勨�滃紑濮嬧�濈敱 ProceedWithSlotMap 鍐崇瓥瑙﹀彂銆�
 				// 浠呭綋鏈紑鍚� CompareMapsBeforeProceeding 鏃讹紝鎵嶆部鐢ㄦ棫閫昏緫鐩存帴 Start銆�
+				LOGI("<CModel>ProceedWithCarrier");
 				if (pLoadPort == nullptr || !pLoadPort->isCompareMapsBeforeProceeding()) {
 					m_master.proceedWithCarrier(portIndex);
 				}
@@ -197,6 +202,7 @@
 				// 褰撳墠 S3F17 瑙f瀽缁撴瀯浠呮敮鎸� {DATAID, CarrierAction, CarrierID, PTN}锛屽皻鏈疄鐜颁笂杩版墿灞曞瓧娈电殑瑙f瀽/鏍¢獙銆�
 				// 鏈潵鑻ュ鎴风‘璁� SECS-II 缁撴瀯锛岄渶瑕佸湪 CHsmsPassive::replyCarrierAction() 鎵╁睍瑙f瀽骞跺湪姝ゅ钀藉簱/鏍¢獙銆�
 				// 浠呭湪 CompareMapsBeforeProceeding 鍚敤锛圚ost 妯″紡锛変笅鍏佽姝ゅ姩浣�
+				LOGI("<CModel>ProceedWithSlotMap");
 				if (pLoadPort == nullptr || !pLoadPort->isCompareMapsBeforeProceeding()) {
 					strErrorTxt = "rejected - SlotMap check disabled";
 					return CAACK_5;
@@ -211,13 +217,13 @@
 				return CAACK_0;
 			}
 			else if (_strcmpi(pszCarrierAction, "CarrierRelease") == 0) {
+				LOGI("<CModel>CarrierRelease");
 				m_master.carrierRelease(portIndex);
 				return CAACK_0;
 			}
 
 			strErrorTxt = "rejected - invalid state";
 			return CAACK_5;
-			LOGI("<Model>onCarrierAction %d, %s, %d, %d", DATAID, pszCarrierAction, pszCarrierId, PTN);
 	};
 	listener.onPRJobMultiCreate = [&](void* pFrom, std::vector<SERVO::CProcessJob*>& pjs) -> int {
 		for (auto p : pjs) {

--
Gitblit v1.9.3