| | |
| | | #include "stdafx.h" |
| | | #include "stdafx.h" |
| | | #include "HsmsPassive.h" |
| | | #include "Log.h" |
| | | #include "Model.h" |
| | |
| | | #include <time.h> |
| | | #include <stdlib.h> |
| | | #include <string.h> |
| | | #include <regex> |
| | | |
| | | |
| | | const char ACK[2] = {0, 1}; |
| | | const char* ACK0 = &ACK[0]; |
| | | const char* ACK1 = &ACK[1]; |
| | | |
| | | unsigned __stdcall CimWorkThreadFunction(LPVOID lpParam) |
| | | { |
| | |
| | | m_bCimWorking = FALSE; |
| | | m_hCimWorkEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); |
| | | m_nSessionId = 1; |
| | | m_listener.onEQOffLine = nullptr; |
| | | m_listener.onEQOnLine = nullptr; |
| | | m_listener.onCommand = nullptr; |
| | | m_listener.onEQConstantRequest = nullptr; |
| | | m_listener.onEQConstantSend = nullptr; |
| | | InitializeCriticalSection(&m_criticalSection); |
| | | } |
| | | |
| | |
| | | |
| | | void CHsmsPassive::setListener(SECSListener listener) |
| | | { |
| | | m_listener.onEQConstantRequest = listener.onEQConstantRequest; |
| | | m_listener = listener; |
| | | } |
| | | |
| | | void CHsmsPassive::setActionTimeout(int nSecond) |
| | |
| | | |
| | | } |
| | | |
| | | void CHsmsPassive::linkEventReport(unsigned int CEID, unsigned int RPTID) |
| | | { |
| | | SERVO::CCollectionEvent* pEvent = getEvent(CEID); |
| | | SERVO::CReport* pReport = getReport(RPTID); |
| | | if (pEvent != nullptr) { |
| | | pEvent->setReport(pReport); |
| | | } |
| | | } |
| | | |
| | | void CHsmsPassive::unlinkEventReport(unsigned int CEID) |
| | | { |
| | | SERVO::CCollectionEvent* pEvent = getEvent(CEID); |
| | | if (pEvent != nullptr) { |
| | | pEvent->setReport(nullptr); |
| | | } |
| | | } |
| | | |
| | | SERVO::CReport* CHsmsPassive::defineReport(unsigned int RPTID, std::vector<unsigned int>& vids) |
| | | { |
| | | // 添加定义report |
| | | SERVO::CReport* pReport = new SERVO::CReport(RPTID, vids); |
| | | for (auto vid : vids) { |
| | | SERVO::CVariable* pVariable = getVariable(vid); |
| | | if (pVariable != nullptr) { |
| | | pReport->addVariable(pVariable); |
| | | } |
| | | } |
| | | m_reports.push_back(pReport); |
| | | |
| | | return pReport; |
| | | } |
| | | |
| | | void CHsmsPassive::OnTimer(UINT nTimerid) |
| | | { |
| | | // 所有已发送的Action自加1 |
| | | // 所有已发送的Action自加1 |
| | | Lock(); |
| | | for (auto iter = m_listActionSent.begin(); iter != m_listActionSent.end();) { |
| | | if ((*iter)->incrementAndCheckTimeout()) { |
| | | TRACE("CHsmsPassive::超时\n"); |
| | | TRACE("CHsmsPassive::超时\n"); |
| | | delete (*iter); |
| | | m_listActionSent.erase(iter++); |
| | | } |
| | |
| | | CHsmsAction* pAction = nullptr; |
| | | for (auto iter = m_listActionSent.begin(); iter != m_listActionSent.end(); iter++) { |
| | | if ((*iter)->getSendMessage()->getHeader()->systemBytes == pMessage->getHeader()->systemBytes) { |
| | | LOGI("CHsmsPassive::找到"); |
| | | LOGI("CHsmsPassive::找到"); |
| | | pAction = (*iter); |
| | | m_listActionSent.erase(iter); |
| | | break; |
| | |
| | | Unlock(); |
| | | |
| | | if (pAction != nullptr) { |
| | | LOGI("onRecvMsg::相应处理"); |
| | | LOGI("onRecvMsg::相应处理"); |
| | | delete pAction; |
| | | } |
| | | |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsPassive::loadVarialbles(const char* pszFilepath) |
| | | { |
| | | CStdioFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead)) { |
| | | return -1; |
| | | } |
| | | |
| | | std::regex pattern("^\\d+,.*"); // 匹配以数字+逗号开头的字符串 |
| | | std::vector<SERVO::CVariable*> variables; |
| | | int index, last; |
| | | CString strLine; |
| | | CString strId, strName, strFormat, strRemark; |
| | | while (file.ReadString(strLine)) { |
| | | if (!std::regex_match((LPTSTR)(LPCTSTR)strLine, pattern)) { |
| | | continue; |
| | | } |
| | | |
| | | last = 0; |
| | | index = strLine.Find(",", last); |
| | | if (index < 0) continue; |
| | | strId = strLine.Left(index); |
| | | last = index + 1; |
| | | |
| | | index = strLine.Find(",", last); |
| | | if (index < 0) continue; |
| | | strName = strLine.Mid(last, index - last); |
| | | last = index + 1; |
| | | |
| | | index = strLine.Find(",", last); |
| | | if (index < 0) continue; |
| | | strFormat = strLine.Mid(last, index - last); |
| | | strRemark = strLine.Right(strLine.GetLength() - index - 1); |
| | | strRemark.Replace(_T("\\r\\n"), _T("\r\n")); |
| | | |
| | | SERVO::CVariable* pVarialble = new SERVO::CVariable( |
| | | (LPTSTR)(LPCTSTR)strId, (LPTSTR)(LPCTSTR)strName, (LPTSTR)(LPCTSTR)strFormat, (LPTSTR)(LPCTSTR)strRemark); |
| | | variables.push_back(pVarialble); |
| | | } |
| | | |
| | | if (!variables.empty()) { |
| | | clearAllVariabel(); |
| | | for (auto item : variables) { |
| | | m_variabels.push_back(item); |
| | | } |
| | | } |
| | | |
| | | |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | |
| | | std::vector<SERVO::CVariable*>& CHsmsPassive::getVariables() |
| | | { |
| | | return m_variabels; |
| | | } |
| | | |
| | | SERVO::CVariable* CHsmsPassive::getVariable(int variableId) |
| | | { |
| | | for (auto item : m_variabels) { |
| | | if (item->getVarialbleId() == variableId) { |
| | | return item; |
| | | } |
| | | } |
| | | |
| | | return nullptr; |
| | | } |
| | | |
| | | void CHsmsPassive::clearAllVariabel() |
| | | { |
| | | for (auto item : m_variabels) { |
| | | delete item; |
| | | } |
| | | m_variabels.clear(); |
| | | } |
| | | |
| | | int CHsmsPassive::loadReports(const char* pszFilepath) |
| | | { |
| | | CStdioFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead)) { |
| | | return -1; |
| | | } |
| | | |
| | | std::regex pattern("^\\d+,\\(\\d+(,\\d+)*\\).*"); // 匹配以数字+逗号开头的字符串 |
| | | std::vector<SERVO::CReport*> reports; |
| | | int index; |
| | | CString strLine, strVariable; |
| | | CString strId; |
| | | while (file.ReadString(strLine)) { |
| | | if (!std::regex_match((LPTSTR)(LPCTSTR)strLine, pattern)) { |
| | | continue; |
| | | } |
| | | |
| | | index = strLine.Find(",", 0); |
| | | if (index < 0) continue; |
| | | strId = strLine.Left(index); |
| | | strVariable = strLine.Right(strLine.GetLength() - index - 1); |
| | | strVariable.Delete(0); |
| | | strVariable.Delete(strVariable.GetLength() - 1); |
| | | auto vids = parseVidList(strVariable); |
| | | |
| | | SERVO::CReport* pReport = new SERVO::CReport(atoi((LPTSTR)(LPCTSTR)strId), vids); |
| | | for (auto vid : vids) { |
| | | SERVO::CVariable* pVariable = getVariable(vid); |
| | | if (pVariable != nullptr) { |
| | | pReport->addVariable(pVariable); |
| | | } |
| | | } |
| | | |
| | | reports.push_back(pReport); |
| | | } |
| | | |
| | | if (!reports.empty()) { |
| | | clearAllReport(); |
| | | for (auto item : reports) { |
| | | m_reports.push_back(item); |
| | | } |
| | | } |
| | | |
| | | |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | |
| | | std::vector<SERVO::CReport*>& CHsmsPassive::getReports() |
| | | { |
| | | return m_reports; |
| | | } |
| | | |
| | | SERVO::CReport* CHsmsPassive::getReport(int rptid) |
| | | { |
| | | for (auto item : m_reports) { |
| | | if (item->getReportId() == rptid) { |
| | | return item; |
| | | } |
| | | } |
| | | |
| | | return nullptr; |
| | | } |
| | | |
| | | bool CHsmsPassive::removeReport(int rptid) |
| | | { |
| | | for (auto iter = m_reports.begin(); iter != m_reports.end(); ++iter) { |
| | | if ((*iter)->getReportId() == rptid) { |
| | | delete (*iter); |
| | | m_reports.erase(iter); |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | void CHsmsPassive::clearAllReport() |
| | | { |
| | | for (auto item : m_reports) { |
| | | delete item; |
| | | } |
| | | m_reports.clear(); |
| | | } |
| | | |
| | | int CHsmsPassive::loadCollectionEvents(const char* pszFilepath) |
| | | { |
| | | CStdioFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead)) { |
| | | return -1; |
| | | } |
| | | |
| | | std::regex pattern("^\\d+,[^,]*,[^,]*,\\(\\d+(,\\d+)*\\).*"); // 匹配以数字+逗号开头的字符串 |
| | | std::vector<SERVO::CCollectionEvent*> events; |
| | | int index, last; |
| | | CString strLine, strRPTIDs; |
| | | CString strId, strName, strDescription; |
| | | while (file.ReadString(strLine)) { |
| | | if (!std::regex_match((LPTSTR)(LPCTSTR)strLine, pattern)) { |
| | | continue; |
| | | } |
| | | |
| | | last = 0; |
| | | index = strLine.Find(",", last); |
| | | if (index < 0) continue; |
| | | strId = strLine.Left(index); |
| | | last = index + 1; |
| | | |
| | | index = strLine.Find(",", last); |
| | | if (index < 0) continue; |
| | | strName = strLine.Mid(last, index - last); |
| | | last = index + 1; |
| | | |
| | | index = strLine.Find(",", last); |
| | | if (index < 0) continue; |
| | | strDescription = strLine.Mid(last, index - last); |
| | | strRPTIDs = strLine.Right(strLine.GetLength() - index - 1); |
| | | strRPTIDs.Delete(0); |
| | | strRPTIDs.Delete(strRPTIDs.GetLength() - 1); |
| | | auto prtids = parseVidList(strRPTIDs); |
| | | |
| | | SERVO::CCollectionEvent* pEvent = new SERVO::CCollectionEvent( |
| | | atoi(strId), (LPTSTR)(LPCTSTR)strName, (LPTSTR)(LPCTSTR)strDescription, prtids); |
| | | for (auto rptid : prtids) { |
| | | SERVO::CReport* pReport = getReport(rptid); |
| | | if (pReport != nullptr) { |
| | | pEvent->addReport(pReport); |
| | | } |
| | | } |
| | | events.push_back(pEvent); |
| | | } |
| | | |
| | | if (!events.empty()) { |
| | | clearAllCollectionEvent(); |
| | | for (auto item : events) { |
| | | m_collectionEvents.push_back(item); |
| | | } |
| | | } |
| | | |
| | | |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | |
| | | std::vector<SERVO::CCollectionEvent*>& CHsmsPassive::getCollectionEvents() |
| | | { |
| | | return m_collectionEvents; |
| | | } |
| | | |
| | | void CHsmsPassive::clearAllCollectionEvent() |
| | | { |
| | | for (auto item : m_collectionEvents) { |
| | | delete item; |
| | | } |
| | | m_collectionEvents.clear(); |
| | | } |
| | | |
| | | SERVO::CCollectionEvent* CHsmsPassive::getEvent(unsigned short CEID) |
| | | { |
| | | for (auto item : m_collectionEvents) { |
| | | if (item->getEventId() == CEID) { |
| | | return item; |
| | | } |
| | | } |
| | | |
| | | return nullptr; |
| | | } |
| | | |
| | | std::vector<unsigned int> CHsmsPassive::parseVidList(CString& strNums) |
| | | { |
| | | // 1. 先去掉可能出现的空白符(空格、制表符等) |
| | | strNums.Trim(); |
| | | |
| | | // 2️. |
| | | std::vector<unsigned int> result; |
| | | int i = 0; |
| | | CString strVid; |
| | | while (1) { |
| | | if (!AfxExtractSubString(strVid, (LPCTSTR)strNums, i, ',')) { |
| | | break; |
| | | } |
| | | if (!strVid.IsEmpty()) // 防御性检查 |
| | | result.push_back(std::stoi((LPTSTR)(LPCTSTR)strVid)); |
| | | i++; |
| | | |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | int CHsmsPassive::init(CModel* pModel, const char* pszName, unsigned int port) |
| | |
| | | auto onStatusChanged = [&](void* pFrom, STATE state) -> void { |
| | | m_pModel->notifyInt(RX_CODE_PASSIVE_STATUS_CHANGED, (int)state); |
| | | |
| | | // 连上之后发S1F1 |
| | | // 修改为不主动发送,而是响应 |
| | | // 连上之后发S1F1 |
| | | // 修改为不主动发送,而是响应 |
| | | /* |
| | | if (STATE::SELECTED == state) { |
| | | m_bAreYouThereRequest = FALSE; |
| | |
| | | HEADER* pHeader = pMessage->getHeader(); |
| | | int nStream = (pHeader->stream & 0x7F); |
| | | |
| | | LOGI("<HSMS>收到消息 S%dF%d", nStream, pHeader->function); |
| | | LOGI("<HSMS>收到消息 S%dF%d", nStream, pHeader->function); |
| | | if (nStream == 1 && pHeader->function == 1) { |
| | | // S1F1 |
| | | replyAreYouThere(pMessage); |
| | |
| | | else if (nStream == 1 && pHeader->function == 13) { |
| | | replyEstablishCommunications(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 15) { |
| | | replyOffLine(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 17) { |
| | | replyOnLine(pMessage); |
| | | } |
| | | else if (nStream == 2 && pHeader->function == 13) { |
| | | replyEquipmentConstant(pMessage); |
| | | replyEquipmentConstantRequest(pMessage); |
| | | } |
| | | else if (nStream == 2 && pHeader->function == 15) { |
| | | replyEquipmentConstantSend(pMessage); |
| | | } |
| | | else if (nStream == 2 && pHeader->function == 31) { |
| | | replyDatetime(pMessage); |
| | | } |
| | | else if (nStream == 2 && pHeader->function == 33) { |
| | | replyDefineReport(pMessage); |
| | | } |
| | | else if (nStream == 2 && pHeader->function == 35) { |
| | | replyLinkEventReport(pMessage); |
| | | } |
| | | else if (nStream == 2 && pHeader->function == 37) { |
| | | replyEanbleDisableEventReport(pMessage); |
| | | } |
| | | else if (nStream == 2 && pHeader->function == 41) { |
| | | replyCommand(pMessage); |
| | | } |
| | | else if (nStream == 5 && pHeader->function == 3) { |
| | | replyEanbleDisableAlarmReport(pMessage); |
| | |
| | | listener.funError = onError; |
| | | m_pPassive->setListener(listener); |
| | | |
| | | // 启动工作线程 |
| | | // 启动工作线程 |
| | | m_bCimWorking = TRUE; |
| | | m_hCimWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, ::CimWorkThreadFunction, this, |
| | | 0, &m_nCimWorkThrdaddr); |
| | |
| | | |
| | | int CHsmsPassive::term() |
| | | { |
| | | // 结束线程 |
| | | // 结束线程 |
| | | m_bCimWorking = FALSE; |
| | | SetEvent(m_hCimWorkEvent); |
| | | if (m_hCimWorkThreadHandle != NULL) { |
| | |
| | | m_pPassive = NULL; |
| | | } |
| | | |
| | | clearAllVariabel(); |
| | | clearAllReport(); |
| | | clearAllCollectionEvent(); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | |
| | | { |
| | | while (m_bCimWorking) { |
| | | |
| | | // 待退出信号或时间到 |
| | | // 待退出信号或时间到 |
| | | int nRet = WaitForSingleObject(m_hCimWorkEvent, INFINITE); |
| | | ResetEvent(m_hCimWorkEvent); |
| | | if (!m_bCimWorking) break; |
| | | |
| | | // 取出请求列表并进行处理 |
| | | // 取出请求列表并进行处理 |
| | | std::list<CHsmsAction*> list; |
| | | Lock(); |
| | | list.splice(list.end(), m_listAction); |
| | |
| | | LOGI("<HSMS> [SEND] SysByte=%u sessionId:%d", pMessage->getHeader()->systemBytes, pMessage->getHeader()->sessionId); |
| | | |
| | | if (pAction->isNeedWaitReply()) { |
| | | // 如果需要等待回复 |
| | | // 如果需要等待回复 |
| | | int nRet = WaitForSingleObject(pAction->getEvent(), pAction->getTimeout() * 1000); |
| | | if (nRet == WAIT_TIMEOUT) { |
| | | TRACE("Timeout...\n"); |
| | | CContext* pContext = pAction->getContext(); |
| | | if (pContext != NULL) { |
| | | //pContext->setRetCode(CRC_TIMEOUT); |
| | | //pContext->setRetMsg("超时"); |
| | | //pContext->setRetMsg("超时"); |
| | | //pContext->setEvent(); |
| | | } |
| | | } |
| | |
| | | return 0; |
| | | } |
| | | |
| | | // 通用的reply ack函数 |
| | | // 通用的reply ack函数 |
| | | void CHsmsPassive::replyAck(int s, int f, unsigned int systemBytes, BYTE ack, const char* pszAckName) |
| | | { |
| | | IMessage* pMessage = NULL; |
| | |
| | | return 0; |
| | | } |
| | | |
| | | // S1F14 |
| | | // S1F15 |
| | | int CHsmsPassive::replyOffLine(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | |
| | | // 交由上层应用来获取机器常量值 |
| | | if (m_listener.onEQOffLine != nullptr) { |
| | | m_listener.onEQOffLine(this); |
| | | } |
| | | |
| | | |
| | | // 回复 |
| | | replyAck(1, 16, pRecv->getHeader()->systemBytes, BYTE(0), "OFLACK"); |
| | | return 0; |
| | | } |
| | | |
| | | // S1F17 |
| | | int CHsmsPassive::replyOnLine(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | |
| | | // 交由上层应用来获取机器常量值 |
| | | if (m_listener.onEQOnLine != nullptr) { |
| | | m_listener.onEQOnLine(this); |
| | | } |
| | | |
| | | |
| | | // 回复 |
| | | replyAck(1, 18, pRecv->getHeader()->systemBytes, BYTE(0), "ONLACK"); |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsPassive::replyEstablishCommunications(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | |
| | | ASSERT(pMessage); |
| | | |
| | | ISECS2Item* pItem = pMessage->getBody(); |
| | | pItem->addBinaryItem(BYTE(0), "COMMACK"); |
| | | pItem->addBinaryItem(ACK0, 1, "COMMACK"); |
| | | ISECS2Item* pList = pItem->addItem(); |
| | | pList->addItem(m_strEquipmentModelType.c_str(), "MDLN"); |
| | | pList->addItem(m_strSoftRev.c_str(), "SOFTREV"); |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SECS Msg SEND]S1F14 (SysByte=%u)", pMessage->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SECS Msg SEND]%s", pMessage->toString()); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | // S2F13 |
| | | int CHsmsPassive::replyEquipmentConstant(IMessage* pRecv) |
| | | int CHsmsPassive::replyEquipmentConstantRequest(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | |
| | | // 要获取的常量表表 |
| | | // 要获取的常量表表 |
| | | BOOL bCheckData = FALSE; |
| | | std::vector<unsigned int> ecids; |
| | | std::vector<EQConstant> eqcs; |
| | | { |
| | | ISECS2Item* pItem = pRecv->getBody(); |
| | | int ecidSize = pItem->getSubItemSize(); |
| | | for (int i = 0; i < ecidSize; i++) { |
| | | EQConstant eqc; |
| | | unsigned short id; |
| | | if (pItem->getSubItemU2(i, id)) { |
| | | ecids.push_back((int)id); |
| | | eqc.id = id; |
| | | eqcs.push_back(eqc); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 交由上层应用来获取机器常量值 |
| | | std::vector<unsigned int> ecvs; |
| | | // 交由上层应用来获取机器常量值 |
| | | if (m_listener.onEQConstantRequest != nullptr) { |
| | | m_listener.onEQConstantRequest(this, ecids, ecvs); |
| | | m_listener.onEQConstantRequest(this, eqcs); |
| | | } |
| | | |
| | | |
| | | // 回复 |
| | | // 回复 |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1, 14, pRecv->getHeader()->systemBytes); |
| | | ASSERT(pMessage); |
| | | ISECS2Item* pItem = pMessage->getBody(); |
| | | for (auto item : ecvs) { |
| | | pItem->addU2Item(item, "ECV"); |
| | | for (auto& item : eqcs) { |
| | | pItem->addItem(item.szValue, "ECV"); |
| | | } |
| | | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SECS Msg SEND]S2F14 (SysByte=%u)", pMessage->getHeader()->systemBytes); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | // S2F15 |
| | | int CHsmsPassive::replyEquipmentConstantSend(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | |
| | | // 要设置的常量表表 |
| | | BOOL bCheckData = FALSE; |
| | | std::vector<EQConstant> eqcs; |
| | | { |
| | | ISECS2Item* pItem = pRecv->getBody(); |
| | | int ecidSize = pItem->getSubItemSize(); |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 交由上层应用来保存和设置机器常量值 |
| | | std::vector<unsigned int> ecvs; |
| | | if (m_listener.onEQConstantSend != nullptr) { |
| | | m_listener.onEQConstantSend(this, eqcs); |
| | | } |
| | | |
| | | |
| | | // 回复 |
| | | replyAck(2, 16, pRecv->getHeader()->systemBytes, BYTE(0), "EACK"); |
| | | return 0; |
| | | } |
| | | |
| | |
| | | if (pBody == nullptr || pBody->getType() != SITYPE::A) ER_PARAM_ERROR; |
| | | const char* pszMessage; |
| | | if (pBody->getString(pszMessage)) { |
| | | // 更新时间 |
| | | // 更新时间 |
| | | SYSTEMTIME time; |
| | | char szBuffer[20]; |
| | | memcpy(szBuffer, pszMessage, 16); |
| | |
| | | time.wYear = atoi(&szBuffer[0]); |
| | | time.wMilliseconds = 0; |
| | | SetLocalTime(&time); |
| | | if (m_listener.onDatetimeSync != nullptr) { |
| | | m_listener.onDatetimeSync(this, time); |
| | | } |
| | | } |
| | | |
| | | replyAck(2, 32, pRecv->getHeader()->systemBytes, BYTE(0), "TIACK"); |
| | | return 0; |
| | | } |
| | | |
| | | // S2F33 |
| | | int CHsmsPassive::replyDefineReport(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | ISECS2Item* defineItem, *rptListItem, * vidListItem; |
| | | unsigned int dataId, rptid, vid; |
| | | |
| | | if (!pBody->getSubItemU4(0, dataId)) goto MYREPLY; |
| | | rptListItem = pBody->getSubItem(1); |
| | | if (rptListItem == nullptr) goto MYREPLY; |
| | | if (rptListItem->getSubItemSize() == 0) { |
| | | clearAllReport(); |
| | | goto MYREPLY; |
| | | } |
| | | |
| | | for (int i = 0; i < rptListItem->getSubItemSize(); i++) { |
| | | defineItem = rptListItem->getSubItem(i); |
| | | if (defineItem == nullptr) continue; |
| | | |
| | | std::vector<unsigned int> vids; |
| | | SERVO::CReport* pReport = nullptr; |
| | | vidListItem = defineItem->getSubItem(1); |
| | | if (defineItem->getSubItemU4(0, rptid) |
| | | && vidListItem != nullptr) { |
| | | for (int k = 0; k < vidListItem->getSubItemSize(); k++) { |
| | | if (vidListItem->getSubItemU4(k, vid)) { |
| | | vids.push_back(vid); |
| | | } |
| | | } |
| | | } |
| | | |
| | | removeReport(rptid); |
| | | if (!vids.empty()) { |
| | | pReport = defineReport(rptid, vids); |
| | | } |
| | | |
| | | // 检验结果是否正确 |
| | | if (pReport != nullptr) { |
| | | auto variables = pReport->getVariables(); |
| | | for (auto item : variables) { |
| | | LOGE("=== prtid:%d, vid:%d", rptid, item->getVarialbleId()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | MYREPLY: |
| | | replyAck(2, 34, pRecv->getHeader()->systemBytes, BYTE(0), "DRACK"); |
| | | return 0; |
| | | } |
| | | |
| | | // S2F35 |
| | | int CHsmsPassive::replyLinkEventReport(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | ISECS2Item* linkItem, *ceidListItem, *rptListItem; |
| | | unsigned int dataId, ceid, rptid; |
| | | if (!pBody->getSubItemU4(0, dataId)) goto MYREPLY; |
| | | ceidListItem = pBody->getSubItem(1); |
| | | if (ceidListItem == nullptr) goto MYREPLY; |
| | | for (int i = 0; i < ceidListItem->getSubItemSize(); i++) { |
| | | linkItem = ceidListItem->getSubItem(i); |
| | | if (linkItem == nullptr) continue; |
| | | rptListItem = linkItem->getSubItem(1); |
| | | if (linkItem->getSubItemU4(0, ceid) |
| | | && rptListItem != nullptr) { |
| | | int prtCount = rptListItem->getSubItemSize(); |
| | | if (prtCount == 0) { |
| | | unlinkEventReport(ceid); |
| | | } |
| | | else { |
| | | for (int k = 0; k < prtCount; k++) { |
| | | if (rptListItem->getSubItemU4(k, rptid)) { |
| | | linkEventReport(ceid, rptid); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 检验结果是否正确 |
| | | for (auto item : m_collectionEvents) { |
| | | LOGE("=== ceid:%d, prtid:%d", item->getEventId(), item->getPortID()); |
| | | } |
| | | |
| | | MYREPLY: |
| | | replyAck(2, 36, pRecv->getHeader()->systemBytes, BYTE(0), "LRACK"); |
| | | return 0; |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | bCheckData = TRUE; |
| | | LOGI("EanbleDisableAlarm bEnable:%s", bEnable ? _T("YES") : _T("NO")); |
| | | for (auto item : ids) { |
| | | LOGI("ID:%u", item); |
| | | if (m_listener.onEnableDisableEventReport != nullptr) { |
| | | m_listener.onEnableDisableEventReport(this, bEnable, ids); |
| | | } |
| | | } |
| | | |
| | | |
| | | MYREPLY: |
| | | replyAck(2, 38, pRecv->getHeader()->systemBytes, BYTE(0), "ERACK"); |
| | | replyAck(2, 38, pRecv->getHeader()->systemBytes, |
| | | bCheckData ? BYTE(0) : BYTE(1), "ERACK"); |
| | | return 0; |
| | | } |
| | | |
| | | // S2F41 |
| | | int CHsmsPassive::replyCommand(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | if (pBody == nullptr || pBody->getType() != SITYPE::A) ER_PARAM_ERROR; |
| | | |
| | | |
| | | |
| | | BOOL bCheckData = FALSE; |
| | | const char* pszCmdName; |
| | | std::vector<CommandParameter> params; |
| | | { |
| | | ISECS2Item* pItemParams, *pItemParam; |
| | | ISECS2Item* pItem = pRecv->getBody(); |
| | | if (pItem->getSubItemSize() < 2) goto MYREPLY; |
| | | if (!pItem->getSubItemString(0, pszCmdName)) goto MYREPLY; |
| | | pItemParams = pItem->getSubItem(1); |
| | | if (pItemParams == nullptr || pItemParams->getType() != SITYPE::L) goto MYREPLY; |
| | | for (int i = 0; i < pItemParams->getSubItemSize(); i++) { |
| | | const char* pszParamName, * pszParamValue; |
| | | pItemParam = pItemParams->getSubItem(i); |
| | | if (pItemParam != nullptr |
| | | && pItemParam->getSubItemString(0, pszParamName) |
| | | && pItemParam->getSubItemString(1, pszParamValue)) { |
| | | CommandParameter cp; |
| | | strcpy_s(cp.szName, COMMAND_NAME_MAX, pszParamName); |
| | | strcpy_s(cp.szValue, COMMAND_VALUE_MAX, pszParamValue); |
| | | params.push_back(cp); |
| | | } |
| | | } |
| | | bCheckData = TRUE; |
| | | } |
| | | |
| | | |
| | | // 回调到应用层 |
| | | if (bCheckData) { |
| | | if (m_listener.onCommand != nullptr) { |
| | | m_listener.onCommand(this, pszCmdName, params); |
| | | } |
| | | } |
| | | |
| | | MYREPLY: |
| | | replyAck(2, 42, pRecv->getHeader()->systemBytes, BYTE(0), "ERACK"); |
| | | return 0; |
| | | } |
| | | |
| | |
| | | if (!pItem->getSubItemU4(1, ALID)) goto MYREPLY; |
| | | bCheckData = TRUE; |
| | | LOGI("EanbleDisableAlarmReport ALED:0x%02x, ALID:%d", ALED[0], ALID); |
| | | |
| | | double d; |
| | | float f; |
| | | pItem->getSubItemF4(2, f); |
| | | pItem->getSubItemF8(3, d); |
| | | LOGI("EanbleDisableAlarmReport d:%lf, f:%f", |
| | | d, f); |
| | | /* |
| | | unsigned long long n1; |
| | | unsigned int n2; |
| | | unsigned short n3; |
| | | unsigned char n4; |
| | | long long sn1; |
| | | int sn2; |
| | | short sn3; |
| | | char sn4; |
| | | pItem->getSubItemU8(2, n1); |
| | | pItem->getSubItemU4(3, n2); |
| | | pItem->getSubItemU2(4, n3); |
| | | pItem->getSubItemU1(5, n4); |
| | | pItem->getSubItemI8(6, sn1); |
| | | pItem->getSubItemI4(7, sn2); |
| | | pItem->getSubItemI2(8, sn3); |
| | | pItem->getSubItemI1(9, sn4); |
| | | |
| | | LOGI("EanbleDisableAlarmReport n1:%llu, n2:%u, n3:%hu, n4:%hhu", |
| | | n1, n2, n3, n4); |
| | | LOGI("EanbleDisableAlarmReport sn1:%lld, sn2:%d, sn3:%hd, sn4:%hhd", |
| | | sn1, sn2, sn3, sn4); |
| | | */ |
| | | if (m_listener.onEnableDisableAlarmReport != nullptr) { |
| | | m_listener.onEnableDisableAlarmReport(this, ALED[0] != 0, ALID); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | char szALCD[1]; |
| | | szALCD[0] = ALCD & 0xff; |
| | | |
| | | Lock(); |
| | | CHsmsAction* pAction = new CHsmsAction(ACTION_ALARM_REPORT, TRUE, m_nActionTimeout); |
| | | m_listAction.push_back(pAction); |
| | |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 5 | REPLY, 1, ++m_nSystemByte); |
| | | ASSERT(pMessage); |
| | | ISECS2Item* pItem = pMessage->getBody(); |
| | | pItem->addBinaryItem(BYTE(ALCD & 0xff), "ALCD"); |
| | | pItem->addBinaryItem(szALCD, 1, "ALCD"); |
| | | pItem->addU4Item(ALID, "ALID"); |
| | | pItem->addItem(ALTX, "ALTX"); |
| | | pAction->setSendMessage(pMessage); |
| | |
| | | return ER_NOERROR; |
| | | } |
| | | |
| | | // S6F11 |
| | | int CHsmsPassive::requestEventReportSend(unsigned int DATAID, unsigned int CEID, const std::vector<std::string>& values) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | SERVO::CCollectionEvent* pEvent = getEvent(CEID); |
| | | if (pEvent == nullptr) { |
| | | return ER_NO_EVENT; |
| | | } |
| | | if (pEvent == nullptr) { |
| | | return ER_UNLINK_EVENT_REPORT; |
| | | } |
| | | |
| | | Lock(); |
| | | CHsmsAction* pAction = new CHsmsAction(ACTION_EVENT_REPORT, TRUE, m_nActionTimeout); |
| | | m_listAction.push_back(pAction); |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 6 | REPLY, 11, ++m_nSystemByte); |
| | | ASSERT(pMessage); |
| | | ISECS2Item* pItem = pMessage->getBody(); |
| | | pItem->addU4Item(DATAID, "DATAID"); |
| | | pItem->addU4Item(CEID, "CEID"); |
| | | ISECS2Item* pItemList1 = pItem->addItem(); |
| | | ISECS2Item* pItemList2 = pItemList1->addItem(); |
| | | pItemList2->addU4Item(pEvent->getPortID(), "RPTID"); |
| | | ISECS2Item* pItemList3 = pItemList2->addItem(); |
| | | for (auto item : values) { |
| | | pItemList3->addItem(item.c_str(), "V"); |
| | | } |
| | | pAction->setSendMessage(pMessage); |
| | | |
| | | SetEvent(m_hCimWorkEvent); |
| | | Unlock(); |
| | | |
| | | return ER_NOERROR; |
| | | } |
| | | |
| | | |
| | | |