| | |
| | | #include "pch.h" |
| | | #include "pch.h" |
| | | #include "CHsmsActive.h" |
| | | #include "Log.h" |
| | | |
| | | |
| | | static unsigned int DATAID = 1; |
| | | static unsigned short DATAID = 1; |
| | | |
| | | CHsmsActive::CHsmsActive() |
| | | { |
| | |
| | | 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()); |
| | | |
| | |
| | | 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(); |
| | |
| | | return 0; |
| | | } |
| | | |
| | | // 通用的reply ack函数 |
| | | // 通用的reply ack函数 |
| | | void CHsmsActive::replyAck(int s, int f, unsigned int systemBytes, BYTE ack, const char* pszAckName) |
| | | { |
| | | IMessage* pMessage = NULL; |
| | |
| | | #pragma once |
| | | #pragma once |
| | | #include <string> |
| | | #include <vector> |
| | | #include <map> |
| | |
| | | // Deselect Request |
| | | int hsmsDeselectRequest(); |
| | | |
| | | // 建立通讯(S1F13) |
| | | // 建立通讯(S1F13) |
| | | int hsmsEstablishCommunications(); |
| | | |
| | | // Are You There |
| | |
| | | // 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, |
| | |
| | | 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); |
| | | |
| | |
| | | // S14F9 |
| | | int hsmsCreateControlJob(const char* pszControlJobId, std::vector<std::string>& processJobIds); |
| | | |
| | | // 通过的reply函数 |
| | | // 通过的reply函数 |
| | | void replyAck(int s, int f, unsigned int systemBytes, BYTE ack, const char* pszAckName); |
| | | |
| | | // reply ack0 |
| | |
| | | { |
| | | 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); |
| | | } |
| | |
| | | #include "afxdialogex.h" |
| | | #include "Common.h" |
| | | #include <regex> |
| | | #include <string> |
| | | #include <vector> |
| | | #include "CTerminalDisplayDlg.h" |
| | | #include "CEDEventReportDlg.h" |
| | | #include "CDefineReportsDlg.h" |
| | |
| | | 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) |
| | |
| | | // 执行此操作 |
| | | 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); |
| | |
| | | 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); |
| | |
| | | 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); |
| | |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonCreateCj() |
| | | { |
| | | std::vector<std::string> processJobIds = {"PJ0001", "PJ0003"}; |
| | | std::vector<std::string> processJobIds = {"PJ0001"}; |
| | | theApp.m_model.m_pHsmsActive->hsmsCreateControlJob("CJ5007", processJobIds); |
| | | } |
| | |
| | | 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(); |
| | |
| | | #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 |
| | | // |
| | |
| | | #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 |
| | |
| | | |
| | | |
| | | // 模拟测试 |
| | | /* |
| | | if (m_nIndex == 0) { |
| | | static int ii = 0; |
| | | ii++; |
| | |
| | | portStatusReport.setCassetteId("CID1001"); |
| | | int nRet = portStatusReport.serialize(szBuffer, 64); |
| | | decodePortStatusReport(pStep, szBuffer, 64); |
| | | LOGI("<CLoadPort>Port1载入模拟数据, id:CID1001 map: 0xf"); |
| | | } |
| | | } |
| | | if (m_nIndex == 1) { |
| | |
| | | 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) |
| | |
| | | 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; |
| | |
| | | |
| | | |
| | | this->saveState(); |
| | | if (m_listener.onControlJobChanged) { |
| | | m_listener.onControlJobChanged(this); |
| | | } |
| | | |
| | | return (int)m_processJobs.size(); |
| | | } |
| | |
| | | pjs.push_back(pj); |
| | | } |
| | | |
| | | ASSERT(m_listener.onPRJobMultiCreate != nullptr); |
| | | int nRet = m_listener.onPRJobMultiCreate(this, pjs); |
| | | |
| | | |
| | | // 回复报文 |
| | | IMessage* pMessage = NULL; |
| | |
| | | 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; |
| | |
| | | { |
| | | // 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() |
| | |
| | | |
| | | 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) { |
| | | // 文档流程:ProceedWithCarrier 之后设备进入 Check SlotMap(WFH), |
| | | // 真正的“开始”由 ProceedWithSlotMap 决策触发。 |
| | | // 仅当未开启 CompareMapsBeforeProceeding 时,才沿用旧逻辑直接 Start。 |
| | | LOGI("<CModel>ProceedWithCarrier"); |
| | | if (pLoadPort == nullptr || !pLoadPort->isCompareMapsBeforeProceeding()) { |
| | | m_master.proceedWithCarrier(portIndex); |
| | | } |
| | |
| | | // 当前 S3F17 解析结构仅支持 {DATAID, CarrierAction, CarrierID, PTN},尚未实现上述扩展字段的解析/校验。 |
| | | // 未来若客户确认 SECS-II 结构,需要在 CHsmsPassive::replyCarrierAction() 扩展解析并在此处落库/校验。 |
| | | // 仅在 CompareMapsBeforeProceeding 启用(Host 模式)下允许此动作 |
| | | LOGI("<CModel>ProceedWithSlotMap"); |
| | | if (pLoadPort == nullptr || !pLoadPort->isCompareMapsBeforeProceeding()) { |
| | | strErrorTxt = "rejected - SlotMap check disabled"; |
| | | return CAACK_5; |
| | |
| | | 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) { |