| | |
| | | #include "Log.h" |
| | | #include "Model.h" |
| | | #include "Common.h" |
| | | #include "RecipeManager.h" |
| | | #include <time.h> |
| | | #include <iostream> |
| | | #include <time.h> |
| | |
| | | #include <algorithm> |
| | | #include <set> |
| | | #include <regex> |
| | | #include <sstream> |
| | | |
| | | // ---- Encoding helpers ---- |
| | | static bool hasUtf8Bom(const std::string& s) |
| | | { |
| | | return s.size() >= 3 && |
| | | static_cast<unsigned char>(s[0]) == 0xEF && |
| | | static_cast<unsigned char>(s[1]) == 0xBB && |
| | | static_cast<unsigned char>(s[2]) == 0xBF; |
| | | } |
| | | |
| | | static bool isLikelyUtf8(const std::string& s) |
| | | { |
| | | // Simple heuristic: try to convert; if success without errors, treat as UTF-8. |
| | | int wlen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.c_str(), (int)s.size(), nullptr, 0); |
| | | return wlen > 0; |
| | | } |
| | | |
| | | static CStringW Utf8ToWide(const char* psz) |
| | | { |
| | | if (psz == nullptr) return L""; |
| | | int wlen = MultiByteToWideChar(CP_UTF8, 0, psz, -1, nullptr, 0); |
| | | if (wlen <= 0) return L""; |
| | | CStringW ws; |
| | | LPWSTR buf = ws.GetBufferSetLength(wlen - 1); |
| | | MultiByteToWideChar(CP_UTF8, 0, psz, -1, buf, wlen); |
| | | ws.ReleaseBuffer(); |
| | | return ws; |
| | | } |
| | | |
| | | static CStringW AnsiToWide(const char* psz) |
| | | { |
| | | if (psz == nullptr) return L""; |
| | | int wlen = MultiByteToWideChar(CP_ACP, 0, psz, -1, nullptr, 0); |
| | | if (wlen <= 0) return L""; |
| | | CStringW ws; |
| | | LPWSTR buf = ws.GetBufferSetLength(wlen - 1); |
| | | MultiByteToWideChar(CP_ACP, 0, psz, -1, buf, wlen); |
| | | ws.ReleaseBuffer(); |
| | | return ws; |
| | | } |
| | | // ---- End helpers ---- |
| | | |
| | | // ControlState values (keep in sync with Model::ControlState / VariableList.txt) |
| | | static constexpr uint8_t kControlStateOnlineRemote = 5; |
| | | |
| | | |
| | | 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) |
| | | { |
| | |
| | | m_listener.onEQOffLine = nullptr; |
| | | m_listener.onEQOnLine = nullptr; |
| | | m_listener.onCommand = nullptr; |
| | | m_listener.onEQConstantRequest = nullptr; |
| | | m_listener.onEQConstantSend = nullptr; |
| | | m_pActiveAction = nullptr; |
| | | InitializeCriticalSection(&m_criticalSection); |
| | | } |
| | |
| | | SERVO::CReport* pReport = new SERVO::CReport(RPTID, vids); |
| | | for (auto vid : vids) { |
| | | SERVO::CVariable* pVariable = getVariable(vid); |
| | | if (pVariable == nullptr) { |
| | | pVariable = getDataVariable(vid); |
| | | } |
| | | if (pVariable != nullptr) { |
| | | pReport->addVariable(pVariable); |
| | | LOGI("<CHsmsPassive>defineReport RPTID=%d", RPTID); |
| | |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsPassive::loadDataVarialbles(const char* pszFilepath) |
| | | { |
| | | if (pszFilepath == NULL) { |
| | | return -1; |
| | | } |
| | | m_strDataVariableFilepath = pszFilepath; |
| | | m_bDataVariableUtf8 = false; |
| | | m_bDataVariableUtf8Bom = false; |
| | | CFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead | CFile::shareDenyNone)) { |
| | | return -1; |
| | | } |
| | | const ULONGLONG nLen = file.GetLength(); |
| | | if (nLen == 0) { |
| | | return -1; |
| | | } |
| | | std::string buffer; |
| | | buffer.resize(static_cast<size_t>(nLen)); |
| | | file.Read(buffer.data(), static_cast<UINT>(nLen)); |
| | | file.Close(); |
| | | |
| | | if (hasUtf8Bom(buffer)) { |
| | | m_bDataVariableUtf8 = true; |
| | | m_bDataVariableUtf8Bom = true; |
| | | buffer = buffer.substr(3); |
| | | } |
| | | else if (isLikelyUtf8(buffer)) { |
| | | m_bDataVariableUtf8 = true; |
| | | } |
| | | CStringW content = m_bDataVariableUtf8 ? Utf8ToWide(buffer.c_str()) : AnsiToWide(buffer.c_str()); |
| | | |
| | | // Regex: DVID,DV Name,DV Format,DV Remark |
| | | std::wregex pattern(L"^\\d+,[^,]*,[^,]*,.*"); |
| | | std::vector<SERVO::CDataVariable*> dataVars; |
| | | int index; |
| | | CStringW strLine, strId, strName, strFormat, strRemark; |
| | | std::wstringstream ss(content.GetString()); |
| | | auto narrowFromW = [](const CStringW& s) -> std::string { |
| | | int need = WideCharToMultiByte(CP_ACP, 0, s, -1, nullptr, 0, nullptr, nullptr); |
| | | if (need <= 0) return {}; |
| | | std::string out(static_cast<size_t>(need - 1), '\0'); |
| | | WideCharToMultiByte(CP_ACP, 0, s, -1, out.data(), need, nullptr, nullptr); |
| | | return out; |
| | | }; |
| | | std::wstring line; |
| | | while (std::getline(ss, line, L'\n')) { |
| | | strLine = line.c_str(); |
| | | strLine.Trim(); |
| | | if (strLine.IsEmpty()) continue; |
| | | if (!std::regex_match(static_cast<LPCWSTR>(strLine), pattern)) { |
| | | continue; |
| | | } |
| | | index = strLine.Find(L",", 0); |
| | | if (index < 0) continue; |
| | | strId = strLine.Left(index); |
| | | |
| | | strLine = strLine.Right(strLine.GetLength() - index - 1); |
| | | index = strLine.Find(L",", 0); |
| | | if (index < 0) continue; |
| | | strName = strLine.Left(index); |
| | | |
| | | strLine = strLine.Right(strLine.GetLength() - index - 1); |
| | | index = strLine.Find(L",", 0); |
| | | if (index < 0) continue; |
| | | strFormat = strLine.Left(index); |
| | | |
| | | strRemark = strLine.Right(strLine.GetLength() - index - 1); |
| | | strRemark.Replace(L"\\r\\n", L"\r\n"); |
| | | |
| | | std::string sId = narrowFromW(strId); |
| | | std::string sName = narrowFromW(strName); |
| | | std::string sFormat = narrowFromW(strFormat); |
| | | std::string sRemark = narrowFromW(strRemark); |
| | | |
| | | SERVO::CDataVariable* pVarialble = new SERVO::CDataVariable( |
| | | sId.c_str(), |
| | | sName.c_str(), |
| | | sFormat.c_str(), |
| | | sRemark.c_str()); |
| | | dataVars.push_back(pVarialble); |
| | | } |
| | | |
| | | if (!dataVars.empty()) { |
| | | clearAllDataVariabel(); |
| | | for (auto item : dataVars) { |
| | | m_dataVariabels.push_back(item); |
| | | } |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsPassive::loadEquipmentConstants(const char* pszFilepath) |
| | | { |
| | | if (pszFilepath == NULL) return -1; |
| | | m_strEquipmentConstantFilepath = pszFilepath; |
| | | m_bEquipmentConstantUtf8 = false; |
| | | m_bEquipmentConstantUtf8Bom = false; |
| | | |
| | | CFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead | CFile::shareDenyNone)) { |
| | | return -1; |
| | | } |
| | | const ULONGLONG nLen = file.GetLength(); |
| | | if (nLen == 0) { |
| | | return -1; |
| | | } |
| | | std::string buffer; |
| | | buffer.resize(static_cast<size_t>(nLen)); |
| | | file.Read(buffer.data(), static_cast<UINT>(nLen)); |
| | | file.Close(); |
| | | |
| | | if (hasUtf8Bom(buffer)) { |
| | | m_bEquipmentConstantUtf8 = true; |
| | | m_bEquipmentConstantUtf8Bom = true; |
| | | buffer = buffer.substr(3); |
| | | } |
| | | else if (isLikelyUtf8(buffer)) { |
| | | m_bEquipmentConstantUtf8 = true; |
| | | } |
| | | CStringW content = m_bEquipmentConstantUtf8 ? Utf8ToWide(buffer.c_str()) : AnsiToWide(buffer.c_str()); |
| | | if (content.IsEmpty()) return -1; |
| | | |
| | | std::wregex pattern(L"^\\d+,[^,]*,[^,]*,([^,]*),.*"); |
| | | std::vector<EquipmentConstantEntry> constants; |
| | | CStringW strLine, strId, strName, strFormat, strRemark, strDefault; |
| | | std::wstringstream ss(content.GetString()); |
| | | auto narrowFromW = [](const CStringW& s) -> std::string { |
| | | int need = WideCharToMultiByte(CP_ACP, 0, s, -1, nullptr, 0, nullptr, nullptr); |
| | | if (need <= 0) return {}; |
| | | std::string out(static_cast<size_t>(need - 1), '\0'); |
| | | WideCharToMultiByte(CP_ACP, 0, s, -1, out.data(), need, nullptr, nullptr); |
| | | return out; |
| | | }; |
| | | std::wstring line; |
| | | while (std::getline(ss, line, L'\n')) { |
| | | strLine = line.c_str(); |
| | | strLine.Trim(); |
| | | if (strLine.IsEmpty()) continue; |
| | | if (strLine.Find(L"ECID") == 0) continue; // skip header |
| | | if (!std::regex_match(static_cast<LPCWSTR>(strLine), pattern)) { |
| | | continue; |
| | | } |
| | | int last = 0; |
| | | int idx = strLine.Find(L",", last); |
| | | if (idx < 0) continue; |
| | | strId = strLine.Left(idx); |
| | | last = idx + 1; |
| | | |
| | | idx = strLine.Find(L",", last); |
| | | if (idx < 0) continue; |
| | | strName = strLine.Mid(last, idx - last); |
| | | last = idx + 1; |
| | | |
| | | idx = strLine.Find(L",", last); |
| | | if (idx < 0) continue; |
| | | strFormat = strLine.Mid(last, idx - last); |
| | | last = idx + 1; |
| | | |
| | | idx = strLine.Find(L",", last); |
| | | if (idx < 0) continue; |
| | | strRemark = strLine.Mid(last, idx - last); |
| | | last = idx + 1; |
| | | |
| | | strDefault = strLine.Right(strLine.GetLength() - last); |
| | | |
| | | EquipmentConstantEntry entry; |
| | | entry.id = _wtoi(strId); |
| | | entry.name = narrowFromW(strName); |
| | | entry.format = narrowFromW(strFormat); |
| | | entry.remark = narrowFromW(strRemark); |
| | | entry.value = narrowFromW(strDefault); |
| | | constants.push_back(entry); |
| | | } |
| | | |
| | | if (!constants.empty()) { |
| | | m_equipmentConstants = std::move(constants); |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | std::vector<SERVO::CVariable*>& CHsmsPassive::getVariables() |
| | | { |
| | | return m_variabels; |
| | | } |
| | | |
| | | std::vector<SERVO::CDataVariable*>& CHsmsPassive::getDataVariables() |
| | | { |
| | | return m_dataVariabels; |
| | | } |
| | | |
| | | unsigned int CHsmsPassive::getMaxVariableId() const |
| | |
| | | return item; |
| | | } |
| | | } |
| | | // try numeric id string |
| | | if (pszName != nullptr && *pszName) { |
| | | const int id = atoi(pszName); |
| | | if (id > 0) { |
| | | return getVariable(id); |
| | | } |
| | | } |
| | | |
| | | return nullptr; |
| | | } |
| | | |
| | | SERVO::CDataVariable* CHsmsPassive::getDataVariable(int dvid) |
| | | { |
| | | for (auto item : m_dataVariabels) { |
| | | if (item->getVarialbleId() == (unsigned int)dvid) return item; |
| | | } |
| | | return nullptr; |
| | | } |
| | | |
| | | SERVO::CDataVariable* CHsmsPassive::getDataVariable(const char* pszName) |
| | | { |
| | | for (auto item : m_dataVariabels) { |
| | | if (item->getName().compare(pszName) == 0) return item; |
| | | } |
| | | return nullptr; |
| | | } |
| | | |
| | | int CHsmsPassive::getCurrentControlState() |
| | | { |
| | | auto v = getVariable("CurrentControlState"); |
| | | if (v != nullptr) { |
| | | return static_cast<int>(v->getIntValue()); |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | bool CHsmsPassive::isHostCommandAllowed() |
| | | { |
| | | // Only allow host control commands in OnlineRemote. |
| | | return getCurrentControlState() == kControlStateOnlineRemote; |
| | | } |
| | | |
| | | void CHsmsPassive::clearAllVariabel() |
| | |
| | | delete item; |
| | | } |
| | | m_variabels.clear(); |
| | | } |
| | | |
| | | void CHsmsPassive::clearAllDataVariabel() |
| | | { |
| | | for (auto item : m_dataVariabels) { |
| | | delete item; |
| | | } |
| | | m_dataVariabels.clear(); |
| | | } |
| | | |
| | | CStringA WideToUtf8(const CStringW& ws) |
| | |
| | | |
| | | 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); |
| | | } |
| | | else if (auto dv = getDataVariable(pszName)) { |
| | | dv->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); |
| | | } |
| | | else if (auto dv = getDataVariable(pszName)) { |
| | | dv->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); |
| | | } |
| | | else if (auto dv = getDataVariable(pszName)) { |
| | | dv->setValue(vars); |
| | | } |
| | | Unlock(); |
| | | } |
| | | |
| | | void CHsmsPassive::withVariableLock(const std::function<void()>& fn) |
| | | { |
| | | Lock(); |
| | | if (fn) fn(); |
| | | Unlock(); |
| | | } |
| | | |
| | | static bool isValidFormat(const std::string& fmt) |
| | |
| | | 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; |
| | |
| | | } |
| | | file.Close(); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsPassive::writeDataVariablesToFile(const std::string& filepath) |
| | | { |
| | | if (filepath.empty()) return -3; |
| | | |
| | | CFile file; |
| | | if (!file.Open(filepath.c_str(), CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone)) { |
| | | return -3; |
| | | } |
| | | |
| | | const std::string headerAnsi = "DVID,DV Name,DV Format,DV Remark\r\n"; |
| | | if (m_bDataVariableUtf8) { |
| | | if (m_bDataVariableUtf8Bom) { |
| | | const BYTE bom[3] = { 0xEF, 0xBB, 0xBF }; |
| | | file.Write(bom, 3); |
| | | } |
| | | CStringA header = AnsiToUtf8(headerAnsi); |
| | | file.Write(header.GetString(), header.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(headerAnsi.data(), (UINT)headerAnsi.size()); |
| | | } |
| | | |
| | | for (auto v : m_dataVariabels) { |
| | | if (v == nullptr) continue; |
| | | std::string lineAnsi; |
| | | lineAnsi.reserve(256); |
| | | lineAnsi += std::to_string(v->getVarialbleId()); |
| | | lineAnsi.push_back(','); |
| | | lineAnsi += v->getName(); |
| | | lineAnsi.push_back(','); |
| | | lineAnsi += SERVO::CVariable::formatToString(v->getFormat()); |
| | | lineAnsi.push_back(','); |
| | | lineAnsi += v->getRemark(); |
| | | lineAnsi.append("\r\n"); |
| | | |
| | | if (m_bDataVariableUtf8) { |
| | | CStringA outLine = AnsiToUtf8(lineAnsi); |
| | | file.Write(outLine.GetString(), outLine.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(lineAnsi.data(), (UINT)lineAnsi.size()); |
| | | } |
| | | } |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | |
| | |
| | | SERVO::CReport* pReport = new SERVO::CReport(_wtoi(strId), vids); |
| | | for (auto vid : vids) { |
| | | SERVO::CVariable* pVariable = getVariable(vid); |
| | | if (pVariable == nullptr) { |
| | | pVariable = getDataVariable(vid); |
| | | } |
| | | if (pVariable != nullptr) { |
| | | pReport->addVariable(pVariable); |
| | | } |
| | |
| | | SERVO::CReport* pReport = new SERVO::CReport(rptid, vids); |
| | | for (auto vid : vids) { |
| | | SERVO::CVariable* pVariable = getVariable((int)vid); |
| | | if (pVariable == nullptr) { |
| | | pVariable = getDataVariable((int)vid); |
| | | } |
| | | if (pVariable != nullptr) { |
| | | pReport->addVariable(pVariable); |
| | | } |
| | |
| | | SERVO::CReport* pReport = new SERVO::CReport(rptid, vids); |
| | | for (auto vid : vids) { |
| | | SERVO::CVariable* pVariable = getVariable((int)vid); |
| | | if (pVariable == nullptr) { |
| | | pVariable = getDataVariable((int)vid); |
| | | } |
| | | if (pVariable != nullptr) { |
| | | pReport->addVariable(pVariable); |
| | | } |
| | |
| | | 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 == 21) { |
| | | replyDataVariableNamelistRequest(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 23) { |
| | | replyCollectionEventNamelistRequest(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 13) { |
| | | replyEstablishCommunications(pMessage); |
| | |
| | | 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); |
| | | } |
| | |
| | | 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(); |
| | |
| | | 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) { |
| | |
| | | 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); |
| | | |
| | | } |
| | | } |
| | |
| | | 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); |
| | | } |
| | | |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | goto MYREPLY; |
| | | } |
| | | if (!pBody->getSubItemU2(0, SVID)) { |
| | | // also accept I2 or U4 to be tolerant with host implementations |
| | | if (!pBody->getSubItemI2(0, (short&)SVID)) { |
| | | pMessage->getBody()->addU1Item(SVU1, "SV"); |
| | | goto MYREPLY; |
| | | unsigned int svidU4 = 0; |
| | | if (!pBody->getSubItemU4(0, svidU4)) { |
| | | pMessage->getBody()->addU1Item(SVU1, "SV"); |
| | | goto MYREPLY; |
| | | } |
| | | SVID = static_cast<unsigned short>(svidU4); |
| | | } |
| | | } |
| | | |
| | |
| | | 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; |
| | | } |
| | | |
| | | int CHsmsPassive::writeEquipmentConstantsToFile(const std::string& filepath) |
| | | { |
| | | if (filepath.empty()) return -1; |
| | | CFile file; |
| | | if (!file.Open(filepath.c_str(), CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone)) { |
| | | return -1; |
| | | } |
| | | const std::string headerAnsi = "ECID,EC Name,EC Format,EC Remark,Default Value\r\n"; |
| | | if (m_bEquipmentConstantUtf8) { |
| | | if (m_bEquipmentConstantUtf8Bom) { |
| | | const BYTE bom[3] = { 0xEF, 0xBB, 0xBF }; |
| | | file.Write(bom, 3); |
| | | } |
| | | CStringA header = AnsiToUtf8(headerAnsi); |
| | | file.Write(header.GetString(), header.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(headerAnsi.data(), (UINT)headerAnsi.size()); |
| | | } |
| | | for (const auto& e : m_equipmentConstants) { |
| | | std::string line; |
| | | line.reserve(128); |
| | | line += std::to_string(e.id); |
| | | line.push_back(','); |
| | | line += e.name; |
| | | line.push_back(','); |
| | | line += e.format; |
| | | line.push_back(','); |
| | | line += e.remark; |
| | | line.push_back(','); |
| | | line += e.value; |
| | | line.append("\r\n"); |
| | | if (m_bEquipmentConstantUtf8) { |
| | | CStringA out = AnsiToUtf8(line); |
| | | file.Write(out.GetString(), out.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(line.data(), (UINT)line.size()); |
| | | } |
| | | } |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | // S1F21/S1F22 - Data Variable Namelist |
| | | int CHsmsPassive::replyDataVariableNamelistRequest(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); |
| | | } |
| | | } |
| | | } |
| | | |
| | | std::vector<unsigned short> dvids; |
| | | std::set<unsigned short> requested(reqIds.begin(), reqIds.end()); |
| | | Lock(); |
| | | if (reqIds.empty()) { |
| | | for (auto v : m_dataVariabels) { |
| | | if (v) dvids.push_back(static_cast<unsigned short>(v->getVarialbleId())); |
| | | } |
| | | } |
| | | else { |
| | | for (auto id : requested) dvids.push_back(id); |
| | | } |
| | | Unlock(); |
| | | |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1, 22, pRecv->getHeader()->systemBytes); |
| | | ASSERT(pMessage); |
| | | |
| | | ISECS2Item* pList = pMessage->getBody(); // L[n] of {DVID, DVNAME, UNITS} |
| | | for (auto id : dvids) { |
| | | ISECS2Item* pEntry = pList->addItem(); |
| | | pEntry->addU2Item(id, "DVID"); |
| | | SERVO::CDataVariable* v = getDataVariable((int)id); |
| | | if (v != nullptr) { |
| | | pEntry->addItem(v->getName().c_str(), "DVNAME"); |
| | | pEntry->addItem(v->getRemark().c_str(), "UNITS"); |
| | | } |
| | | else { |
| | | pEntry->addItem("", "DVNAME"); |
| | | 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 |
| | |
| | | } |
| | | |
| | | |
| | | // 要获取的常量表表 |
| | | BOOL bCheckData = FALSE; |
| | | std::vector<EQConstant> eqcs; |
| | | { |
| | | ISECS2Item* pItem = pRecv->getBody(); |
| | | int ecidSize = pItem->getSubItemSize(); |
| | | const int ecidSize = pItem ? pItem->getSubItemSize() : 0; |
| | | for (int i = 0; i < ecidSize; i++) { |
| | | EQConstant eqc; |
| | | unsigned short id; |
| | | if (pItem->getSubItemU2(i, id)) { |
| | | EQConstant eqc{}; |
| | | unsigned short id = 0; |
| | | if (pItem && pItem->getSubItemU2(i, id)) { |
| | | eqc.id = id; |
| | | eqcs.push_back(eqc); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 交由上层应用来获取机器常量值 |
| | | if (m_listener.onEQConstantRequest != nullptr) { |
| | | m_listener.onEQConstantRequest(this, eqcs); |
| | | // 空列表表示请求全部 ECID |
| | | if (eqcs.empty()) { |
| | | for (const auto& e : m_equipmentConstants) { |
| | | EQConstant eqc{}; |
| | | eqc.id = e.id; |
| | | strcpy_s(eqc.szValue, EQCONSTANT_VALUE_MAX, e.value.c_str()); |
| | | eqcs.push_back(eqc); |
| | | } |
| | | } else { |
| | | for (auto& item : eqcs) { |
| | | auto it = std::find_if(m_equipmentConstants.begin(), m_equipmentConstants.end(), |
| | | [&](const EquipmentConstantEntry& e) { return e.id == item.id; }); |
| | | if (it != m_equipmentConstants.end()) { |
| | | strcpy_s(item.szValue, EQCONSTANT_VALUE_MAX, it->value.c_str()); |
| | | } else { |
| | | item.szValue[0] = '\0'; // unknown -> empty |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 回复 |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1, 14, pRecv->getHeader()->systemBytes); |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 2, 14, pRecv->getHeader()->systemBytes); |
| | | ASSERT(pMessage); |
| | | ISECS2Item* pItem = pMessage->getBody(); |
| | | for (auto& item : eqcs) { |
| | |
| | | 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; |
| | |
| | | } |
| | | |
| | | |
| | | // 要设置的常量表表 |
| | | BOOL bCheckData = FALSE; |
| | | // 要设置的常量表 |
| | | std::vector<EQConstant> eqcs; |
| | | { |
| | | ISECS2Item* pItem = pRecv->getBody(); |
| | | int ecidSize = pItem->getSubItemSize(); |
| | | int ecidSize = pItem ? pItem->getSubItemSize() : 0; |
| | | for (int i = 0; i < ecidSize; i++) { |
| | | ISECS2Item* pItemEqc = pItem->getSubItem(i); |
| | | if (pItemEqc != nullptr) { |
| | | EQConstant eqc; |
| | | unsigned short eqcid; |
| | | const char* pszValue; |
| | | if (pItemEqc->getSubItemU2(0, eqcid) |
| | | && pItemEqc->getSubItemString(1, pszValue)) { |
| | | eqc.id = eqcid; |
| | | strcpy_s(eqc.szValue, EQCONSTANT_VALUE_MAX, pszValue); |
| | | eqcs.push_back(eqc); |
| | | } |
| | | ISECS2Item* pItemEqc = pItem ? pItem->getSubItem(i) : nullptr; |
| | | if (pItemEqc == nullptr) continue; |
| | | EQConstant eqc{}; |
| | | unsigned short eqcid = 0; |
| | | const char* pszValue = nullptr; |
| | | if (pItemEqc->getSubItemU2(0, eqcid) |
| | | && pItemEqc->getSubItemString(1, pszValue)) { |
| | | eqc.id = eqcid; |
| | | strcpy_s(eqc.szValue, EQCONSTANT_VALUE_MAX, pszValue); |
| | | eqcs.push_back(eqc); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 交由上层应用来保存和设置机器常量值 |
| | | std::vector<unsigned int> ecvs; |
| | | if (m_listener.onEQConstantSend != nullptr) { |
| | | m_listener.onEQConstantSend(this, eqcs); |
| | | // 更新内存表并落盘 |
| | | bool changed = false; |
| | | for (auto& item : eqcs) { |
| | | auto it = std::find_if(m_equipmentConstants.begin(), m_equipmentConstants.end(), |
| | | [&](const EquipmentConstantEntry& e) { return e.id == item.id; }); |
| | | if (it != m_equipmentConstants.end()) { |
| | | it->value = item.szValue; |
| | | changed = true; |
| | | } |
| | | } |
| | | if (changed && !m_strEquipmentConstantFilepath.empty()) { |
| | | writeEquipmentConstantsToFile(m_strEquipmentConstantFilepath); |
| | | } |
| | | |
| | | |
| | |
| | | goto MYREPLY; |
| | | } |
| | | |
| | | if (!isHostCommandAllowed()) { |
| | | CAACK = CAACK_5; |
| | | ERRCODE = CAACK_5; |
| | | strError = "rejected - ControlState not OnlineRemote"; |
| | | goto MYREPLY; |
| | | } |
| | | |
| | | |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | if (pBody == nullptr || pBody->getType() != SITYPE::L) ER_PARAM_ERROR; |
| | |
| | | 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; |
| | |
| | | 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) |
| | | { |
| | |
| | | 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; |
| | |
| | | ISECS2Item* pReplyItemAcks = pReply->getBody()->addItem(); |
| | | ISECS2Item* pReplyItemAck = pReplyItemAcks->addU1Item(0, "OBJACK"); |
| | | ISECS2Item* pReplyItemErrs = pReplyItemAcks->addItem(); |
| | | |
| | | if (!isHostCommandAllowed()) { |
| | | ISECS2Item* pItemError = pReplyItemErrs->addItem(); |
| | | pItemError->addU4Item(2001, "ERRCODE"); |
| | | pItemError->addItem("rejected - ControlState not OnlineRemote", "ERRTEXT"); |
| | | goto MYREPLY; |
| | | } |
| | | |
| | | // 当前只处理类各为ControlJob |
| | | if (_strcmpi(pszObjType, "ControlJob") == 0) { |
| | |
| | | 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); |
| | | |
| | | |
| | |
| | | } |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | if (pBody == nullptr || pBody->getType() != SITYPE::L) ER_PARAM_ERROR; |
| | | |
| | | if (!isHostCommandAllowed()) { |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 16, 16, ++m_nSystemByte); |
| | | ASSERT(pMessage); |
| | | ISECS2Item* pItemPrjobIds = pMessage->getBody()->addItem(); |
| | | ISECS2Item* pItemErrors = pMessage->getBody()->addItem(); |
| | | pItemErrors->addBoolItem(false, "ACKA"); |
| | | ISECS2Item* pItemErrors2 = pItemErrors->addItem(); |
| | | auto err = pItemErrors2->addItem(); |
| | | err->addU4Item(2001, "ERRCODE"); |
| | | err->addItem("rejected - ControlState not OnlineRemote", "ERRTEXT"); |
| | | 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 0; |
| | | } |
| | | |
| | | |
| | | // 解释数据,得到CProcessJob |
| | |
| | | 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); |
| | | |
| | | |