SourceCode/Bond/Servo/Model.cpp
@@ -173,12 +173,39 @@
            return CAACK_3;
         }
         const unsigned int portIndex = PTN - 1;
         SERVO::CLoadPort* pLoadPort = (SERVO::CLoadPort*)m_master.getEquipment(EQ_ID_LOADPORT1 + portIndex);
         if (_strcmpi(pszCarrierAction, "ProceedWithCarrier") == 0) {
            m_master.proceedWithCarrier(PTN);
            // 文档流程:ProceedWithCarrier 之后设备进入 Check SlotMap(WFH),
            // 真正的“开始”由 ProceedWithSlotMap 决策触发。
            // 仅当未开启 CompareMapsBeforeProceeding 时,才沿用旧逻辑直接 Start。
            if (pLoadPort == nullptr || !pLoadPort->isCompareMapsBeforeProceeding()) {
               m_master.proceedWithCarrier(portIndex);
            }
            return CAACK_0;
         }
         else if (_strcmpi(pszCarrierAction, "ProceedWithSlotMap") == 0) {
            // TODO(Host协商):
            // 文档中 ProceedWithSlotMap 可能会携带 LotID / PanelIDList / SlotMap 等数据(最多13片)用于格式校验与绑定。
            // 当前 S3F17 解析结构仅支持 {DATAID, CarrierAction, CarrierID, PTN},尚未实现上述扩展字段的解析/校验。
            // 未来若客户确认 SECS-II 结构,需要在 CHsmsPassive::replyCarrierAction() 扩展解析并在此处落库/校验。
            // 仅在 CompareMapsBeforeProceeding 启用(Host 模式)下允许此动作
            if (pLoadPort == nullptr || !pLoadPort->isCompareMapsBeforeProceeding()) {
               strErrorTxt = "rejected - SlotMap check disabled";
               return CAACK_5;
            }
            m_hsmsPassive.setVariableValue("SlotMapScan", pLoadPort->getScanCassetteMap());
            m_hsmsPassive.setVariableValue("SlotMapDownload", pLoadPort->getDownloadCassetteMap());
            m_hsmsPassive.requestEventReportSend_SlotMapVerificationOK();
            // Host 确认 SlotMap 后再开始加工/流程
            m_master.proceedWithCarrier(portIndex);
            return CAACK_0;
         }
         else if (_strcmpi(pszCarrierAction, "CarrierRelease") == 0) {
            m_master.carrierRelease(PTN);
            m_master.carrierRelease(portIndex);
            return CAACK_0;
         }
@@ -410,6 +437,12 @@
         SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment);
         if (pLoadPort != nullptr) {
            m_hsmsPassive.setVariableValue("CarrierID", pLoadPort->getCassetteId().c_str());
            if (prevStatus != PORT_INUSE && pLoadPort->isCompareMapsBeforeProceeding()) {
               // TODO(Host协商):
               // 文档中标明:1-Empty,3-Exist,因此我们可能需要将uint的map转换为list上传
               m_hsmsPassive.setVariableValue("SlotMap", pLoadPort->getScanCassetteMap());
               m_hsmsPassive.requestEventReportSend_CheckSlotMap();
            }
         }
         m_hsmsPassive.requestEventReportSend_CarrierID_Readed();
      }