| | |
| | | |
| | | int CHsmsPassive::addCollectionEvent(unsigned int CEID, const char* name, const char* desc, const std::vector<unsigned int>& rptids) |
| | | { |
| | | if (getEvent((unsigned short)CEID) != nullptr) { |
| | | if (getEvent((unsigned int)CEID) != nullptr) { |
| | | return -1; |
| | | } |
| | | auto* pEvent = new SERVO::CCollectionEvent(CEID, name, desc, const_cast<std::vector<unsigned int>&>(rptids)); |
| | |
| | | m_collectionEvents.clear(); |
| | | } |
| | | |
| | | SERVO::CCollectionEvent* CHsmsPassive::getEvent(unsigned short CEID) |
| | | SERVO::CCollectionEvent* CHsmsPassive::getEvent(unsigned int CEID) |
| | | { |
| | | for (auto item : m_collectionEvents) { |
| | | if (item->getEventId() == CEID) { |
| | |
| | | replySelectedEquipmentStatusData(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 11) { |
| | | replyStatusVariableNamelistRequest(pMessage); |
| | | // [EAP_MAPPING][S1F11] Status Variable namelist request -> S1F12. |
| | | // If customer requires swapping SV/DV mapping, this is one of the two switch points. |
| | | // Swap target with S1F21 branch below. |
| | | // replyStatusVariableNamelistRequest(pMessage); |
| | | replyDataVariableNamelistRequest(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 21) { |
| | | replyDataVariableNamelistRequest(pMessage); |
| | | // [EAP_MAPPING][S1F21] Data Variable namelist request -> S1F22. |
| | | // If customer requires swapping SV/DV mapping, this is one of the two switch points. |
| | | // Swap target with S1F11 branch above. |
| | | // replyDataVariableNamelistRequest(pMessage); |
| | | replyStatusVariableNamelistRequest(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 23) { |
| | | replyCollectionEventNamelistRequest(pMessage); |
| | |
| | | if (pszBuffer == nullptr) { |
| | | index += sizeof(int); |
| | | for (auto item : m_listActionSpooling) { |
| | | index += item->serialize(pszBuffer, nBufferSize); |
| | | if (item == nullptr || item->getSendMessage() == nullptr) { |
| | | LOGE("<HSMS>skip spooling item: null send message"); |
| | | continue; |
| | | } |
| | | int nRet = item->serialize(nullptr, 0); |
| | | if (nRet <= 0) { |
| | | LOGE("<HSMS>skip spooling item: serialize failed"); |
| | | continue; |
| | | } |
| | | index += nRet; |
| | | } |
| | | |
| | | index += calcSpoolCfgSize(); |
| | |
| | | return index; |
| | | } |
| | | else { |
| | | int nTemp, nRet; |
| | | int nTemp = 0; |
| | | int nRet = 0; |
| | | |
| | | nTemp = (int)m_listActionSpooling.size(); |
| | | for (auto item : m_listActionSpooling) { |
| | | if (item == nullptr || item->getSendMessage() == nullptr) { |
| | | continue; |
| | | } |
| | | if (item->serialize(nullptr, 0) > 0) { |
| | | ++nTemp; |
| | | } |
| | | } |
| | | |
| | | memcpy(&pszBuffer[index], &nTemp, sizeof(int)); |
| | | index += sizeof(int); |
| | | |
| | | for (auto item : m_listActionSpooling) { |
| | | if (item == nullptr || item->getSendMessage() == nullptr) { |
| | | LOGE("<HSMS>skip spooling item: null send message"); |
| | | continue; |
| | | } |
| | | nRet = item->serialize(&pszBuffer[index], nBufferSize); |
| | | if (nRet <= 0) break; |
| | | if (nRet <= 0) { |
| | | LOGE("<HSMS>skip spooling item: serialize failed"); |
| | | continue; |
| | | } |
| | | index += nRet; |
| | | } |
| | | |
| | |
| | | for (int i = 0; i < nTemp; i++) { |
| | | CHsmsAction* pAction = new CHsmsAction(); |
| | | nRet = pAction->unserialize(&pszBuffer[index], nBufferSize - index); |
| | | if (nRet <= 0) break; |
| | | if (nRet <= 0 || pAction->getSendMessage() == nullptr) { |
| | | delete pAction; |
| | | break; |
| | | } |
| | | index += nRet; |
| | | m_listActionSpooling.push_back(pAction); |
| | | } |
| | |
| | | Unlock(); |
| | | if (!selected) { |
| | | IMessage* pMsg = pAction->getSendMessage(); |
| | | if (pMsg == NULL) { |
| | | LOGE("<HSMS>spooling drop: null send message"); |
| | | delete pAction; |
| | | continue; |
| | | } |
| | | uint8_t streamId = 0; |
| | | uint8_t functionId = 0; |
| | | if (pMsg && pMsg->getHeader()) { |
| | |
| | | |
| | | if (pAction->isNeedWaitReply()) { |
| | | // 如果需要等待回复 |
| | | IMessage* pMessage = pAction->getSendMessage(); |
| | | if (pMessage == NULL) { |
| | | LOGE("<HSMS>drop action: null send message"); |
| | | delete pAction; |
| | | continue; |
| | | } |
| | | Lock(); |
| | | m_pActiveAction = pAction; |
| | | IMessage* pMessage = pAction->getSendMessage(); |
| | | Unlock(); |
| | | |
| | | ASSERT(pMessage); |
| | |
| | | Unlock(); |
| | | } |
| | | else { |
| | | IMessage* pMessage = pAction->getSendMessage(); |
| | | if (pMessage == NULL) { |
| | | LOGE("<HSMS>drop action: null send message"); |
| | | delete pAction; |
| | | continue; |
| | | } |
| | | Lock(); |
| | | m_listActionSent.push_back(pAction); |
| | | IMessage* pMessage = pAction->getSendMessage(); |
| | | Unlock(); |
| | | |
| | | ASSERT(pMessage); |
| | |
| | | |
| | | Lock(); |
| | | CHsmsAction* pAction = new CHsmsAction(ACTION_HELLO, FALSE, m_nActionTimeout); |
| | | m_listAction.push_back(pAction); |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1 | REPLY, 1, ++m_nSystemByte); |
| | | ASSERT(pMessage); |
| | | if (HSMS_Create1Message(pMessage, m_nSessionId, 1 | REPLY, 1, ++m_nSystemByte) != 0 || pMessage == NULL) { |
| | | LOGE("<HSMS>S1F1 create message failed"); |
| | | delete pAction; |
| | | Unlock(); |
| | | return ER_CREATED_MESSAGE; |
| | | } |
| | | pAction->setSendMessage(pMessage); |
| | | m_listAction.push_back(pAction); |
| | | |
| | | SetEvent(m_hCimWorkEvent); |
| | | Unlock(); |
| | |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1, 4, pRecv->getHeader()->systemBytes); |
| | | ASSERT(pMessage); |
| | | |
| | | unsigned char SVU1 = 0; |
| | | unsigned short SVID = 0; |
| | | std::vector<unsigned int> reqIds; |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | if (pBody == nullptr || pBody->getType() != SITYPE::L) { |
| | | pMessage->getBody()->addU1Item(SVU1, "SV"); |
| | | goto MYREPLY; |
| | | } |
| | | if (!pBody->getSubItemU2(0, SVID)) { |
| | | // also accept I2 or U4 to be tolerant with host implementations |
| | | if (!pBody->getSubItemI2(0, (short&)SVID)) { |
| | | unsigned int svidU4 = 0; |
| | | if (!pBody->getSubItemU4(0, svidU4)) { |
| | | pMessage->getBody()->addU1Item(SVU1, "SV"); |
| | | goto MYREPLY; |
| | | } |
| | | SVID = static_cast<unsigned short>(svidU4); |
| | | |
| | | // S1F3 supports batch query: {L:n SVID}. S1F4 must return {L:n SV} in the same order. |
| | | const int reqSize = pBody->getSubItemSize(); |
| | | for (int i = 0; i < reqSize; ++i) { |
| | | unsigned int idU4 = 0; |
| | | unsigned short idU2 = 0; |
| | | short idI2 = 0; |
| | | if (pBody->getSubItemU4(i, idU4)) { |
| | | reqIds.push_back(idU4); |
| | | } |
| | | else if (pBody->getSubItemU2(i, idU2)) { |
| | | reqIds.push_back(static_cast<unsigned int>(idU2)); |
| | | } |
| | | else if (pBody->getSubItemI2(i, idI2) && idI2 >= 0) { |
| | | reqIds.push_back(static_cast<unsigned int>(idI2)); |
| | | } |
| | | } |
| | | |
| | | SERVO::CVariable* pVariable = getVariable((int)SVID); |
| | | if (pVariable == nullptr) { |
| | | pMessage->getBody()->addU1Item(SVU1, "SV"); |
| | | goto MYREPLY; |
| | | // L:0 means "all SVIDs". |
| | | if (reqIds.empty()) { |
| | | Lock(); |
| | | for (auto* v : m_variabels) { |
| | | if (v != nullptr) { |
| | | reqIds.push_back(static_cast<unsigned int>(v->getVarialbleId())); |
| | | } |
| | | } |
| | | Unlock(); |
| | | } |
| | | addVariableValueToItem(pMessage->getBody(), pVariable); |
| | | |
| | | for (auto id : reqIds) { |
| | | SERVO::CVariable* pVariable = getVariable((int)id); |
| | | if (pVariable != nullptr) { |
| | | addVariableValueToItem(pMessage->getBody(), pVariable); |
| | | } |
| | | else { |
| | | // Unknown SVID placeholder. |
| | | pMessage->getBody()->addU1Item(0, "SV"); |
| | | } |
| | | } |
| | | |
| | | MYREPLY: |
| | | m_pPassive->sendMessage(pMessage); |
| | |
| | | return 0; |
| | | } |
| | | |
| | | // S1F11 |
| | | // S1F21 |
| | | int CHsmsPassive::replyStatusVariableNamelistRequest(IMessage* pRecv) |
| | | { |
| | | // [EAP_MAPPING][SV_HANDLER] |
| | | // Current behavior: handles S1F11 and replies S1F12 with SVID/SVNAME/UNITS. |
| | | // If customer requires SV/DV swap, this function body can be swapped with |
| | | // replyDataVariableNamelistRequest (or dispatch branches can be swapped instead). |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | std::vector<unsigned short> reqIds; |
| | | std::vector<unsigned int> 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)) { |
| | | unsigned int id = 0; |
| | | unsigned short idU2 = 0; |
| | | short idI2 = 0; |
| | | if (pBody->getSubItemU4(i, id)) { |
| | | reqIds.push_back(id); |
| | | } |
| | | else if (pBody->getSubItemU2(i, idU2)) { |
| | | reqIds.push_back(static_cast<unsigned int>(idU2)); |
| | | } |
| | | else if (pBody->getSubItemI2(i, idI2) && idI2 >= 0) { |
| | | reqIds.push_back(static_cast<unsigned int>(idI2)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Build response list items: {L:3 SVID, SVNAME, UNITS} |
| | | std::vector<unsigned short> svids; |
| | | std::set<unsigned short> requested(reqIds.begin(), reqIds.end()); |
| | | std::vector<unsigned int> svids; |
| | | std::set<unsigned int> requested(reqIds.begin(), reqIds.end()); |
| | | Lock(); |
| | | if (reqIds.empty()) { |
| | | for (auto v : m_variabels) { |
| | | svids.push_back(static_cast<unsigned short>(v->getVarialbleId())); |
| | | svids.push_back(static_cast<unsigned int>(v->getVarialbleId())); |
| | | } |
| | | } |
| | | else { |
| | |
| | | Unlock(); |
| | | |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1, 12, pRecv->getHeader()->systemBytes); |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1, 22, 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"); |
| | | pEntry->addU4Item(id, "SVID"); |
| | | SERVO::CVariable* v = getVariable((int)id); |
| | | if (v != nullptr) { |
| | | pEntry->addItem(v->getName().c_str(), "SVNAME"); |
| | |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | // S1F21/S1F22 - Data Variable Namelist |
| | | // S1F11/S1F12 - Data Variable Namelist |
| | | int CHsmsPassive::replyDataVariableNamelistRequest(IMessage* pRecv) |
| | | { |
| | | // [EAP_MAPPING][DV_HANDLER] |
| | | // Current behavior: handles S1F21 and replies S1F22 with DVID/DVNAME/UNITS. |
| | | // If customer requires SV/DV swap, this function body can be swapped with |
| | | // replyStatusVariableNamelistRequest (or dispatch branches can be swapped instead). |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | std::vector<unsigned short> reqIds; |
| | | std::vector<unsigned int> 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)) { |
| | | unsigned int id = 0; |
| | | unsigned short idU2 = 0; |
| | | short idI2 = 0; |
| | | if (pBody->getSubItemU4(i, id)) { |
| | | reqIds.push_back(id); |
| | | } |
| | | else if (pBody->getSubItemU2(i, idU2)) { |
| | | reqIds.push_back(static_cast<unsigned int>(idU2)); |
| | | } |
| | | else if (pBody->getSubItemI2(i, idI2) && idI2 >= 0) { |
| | | reqIds.push_back(static_cast<unsigned int>(idI2)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | std::vector<unsigned short> dvids; |
| | | std::set<unsigned short> requested(reqIds.begin(), reqIds.end()); |
| | | std::vector<unsigned int> dvids; |
| | | std::set<unsigned int> 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())); |
| | | if (v) dvids.push_back(static_cast<unsigned int>(v->getVarialbleId())); |
| | | } |
| | | } |
| | | else { |
| | |
| | | Unlock(); |
| | | |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1, 22, pRecv->getHeader()->systemBytes); |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1, 12, 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"); |
| | | pEntry->addU4Item(id, "DVID"); |
| | | SERVO::CDataVariable* v = getDataVariable((int)id); |
| | | if (v != nullptr) { |
| | | pEntry->addItem(v->getName().c_str(), "DVNAME"); |
| | |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | std::vector<unsigned short> reqIds; |
| | | std::vector<unsigned int> 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)) { |
| | | unsigned int id = 0; |
| | | unsigned short idU2 = 0; |
| | | if (pBody->getSubItemU4(i, id)) { |
| | | reqIds.push_back(id); |
| | | } |
| | | else if (pBody->getSubItemU2(i, idU2)) { |
| | | reqIds.push_back(static_cast<unsigned int>(idU2)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | struct CEInfo { |
| | | unsigned short id{ 0 }; |
| | | unsigned int id{ 0 }; |
| | | std::string name; |
| | | std::vector<unsigned short> vids; |
| | | std::vector<unsigned int> vids; |
| | | }; |
| | | std::vector<CEInfo> ceInfos; |
| | | { |
| | |
| | | for (auto e : m_collectionEvents) { |
| | | if (e == nullptr) continue; |
| | | CEInfo info; |
| | | info.id = static_cast<unsigned short>(e->getEventId()); |
| | | info.id = static_cast<unsigned int>(e->getEventId()); |
| | | info.name = e->getName(); |
| | | std::set<unsigned short> vidSet; |
| | | std::set<unsigned int> vidSet; |
| | | for (auto rpt : e->getReports()) { |
| | | if (rpt == nullptr) continue; |
| | | for (auto vid : rpt->getVids()) { |
| | | vidSet.insert(static_cast<unsigned short>(vid)); |
| | | vidSet.insert(static_cast<unsigned int>(vid)); |
| | | } |
| | | } |
| | | info.vids.assign(vidSet.begin(), vidSet.end()); |
| | |
| | | for (auto id : reqIds) { |
| | | CEInfo info; |
| | | info.id = id; |
| | | SERVO::CCollectionEvent* e = getEvent(id); |
| | | SERVO::CCollectionEvent* e = getEvent(static_cast<unsigned int>(id)); |
| | | if (e != nullptr) { |
| | | info.name = e->getName(); |
| | | std::set<unsigned short> vidSet; |
| | | std::set<unsigned int> vidSet; |
| | | for (auto rpt : e->getReports()) { |
| | | if (rpt == nullptr) continue; |
| | | for (auto vid : rpt->getVids()) { |
| | | vidSet.insert(static_cast<unsigned short>(vid)); |
| | | vidSet.insert(static_cast<unsigned int>(vid)); |
| | | } |
| | | } |
| | | info.vids.assign(vidSet.begin(), vidSet.end()); |
| | |
| | | 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->addU4Item(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"); |
| | | pVidList->addU4Item(vid, "VID"); |
| | | } |
| | | } |
| | | |
| | |
| | | CHsmsAction* pAction = new CHsmsAction(ACTION_ALARM_REPORT, TRUE, m_nActionTimeout); |
| | | |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 5 | REPLY, 1, ++m_nSystemByte); |
| | | ASSERT(pMessage); |
| | | if (HSMS_Create1Message(pMessage, m_nSessionId, 5 | REPLY, 1, ++m_nSystemByte) != 0 || pMessage == NULL) { |
| | | LOGE("<HSMS>S5F1 create message failed"); |
| | | delete pAction; |
| | | Unlock(); |
| | | return ER_CREATED_MESSAGE; |
| | | } |
| | | ISECS2Item* pItem = pMessage->getBody(); |
| | | pItem->addBinaryItem(szALCD, 1, "ALCD"); |
| | | pItem->addU4Item(ALID, "ALID"); |
| | |
| | | if (pEvent == nullptr) { |
| | | return ER_NO_EVENT; |
| | | } |
| | | // 触发 PauseEvent 检测桩(由 Master 负责实际策略) |
| | | if (m_pModel != nullptr) { |
| | | m_pModel->getMaster().handleCollectionEvent(CEID); |
| | | } |
| | | |
| | | SERVO::CReport* pReport = pEvent->getFirstReport(); |
| | | |
| | |
| | | Lock(); |
| | | CHsmsAction* pAction = new CHsmsAction(ACTION_EVENT_REPORT, TRUE, m_nActionTimeout); |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 6 | REPLY, 11, ++m_nSystemByte); |
| | | ASSERT(pMessage); |
| | | if (HSMS_Create1Message(pMessage, m_nSessionId, 6 | REPLY, 11, ++m_nSystemByte) != 0 || pMessage == NULL) { |
| | | LOGE("<HSMS>S6F11 create message failed"); |
| | | delete pAction; |
| | | Unlock(); |
| | | return ER_CREATED_MESSAGE; |
| | | } |
| | | ISECS2Item* pItem = pMessage->getBody(); |
| | | // pItem->addU2Item(++DATAID, "DATAID"); // 根据别的日志显示DATAID恒为0,所以我们先照使用0 |
| | | pItem->addU2Item(0, "DATAID"); |
| | |
| | | |
| | | int CHsmsPassive::requestEventReportSend_OCR_PanelID_Read_OK() |
| | | { |
| | | return requestEventReportSend("OCR_PanelID_Read_OK"); |
| | | return requestEventReportSend_OCR_PanelID_Read(1); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_OCR_PanelID_Read(short vcrResult) |
| | | { |
| | | const char* eventName = "OCR_PanelID_Read_OK"; |
| | | switch (vcrResult) { |
| | | case 1: // OK & Match |
| | | eventName = "OCR_PanelID_Read_OK"; |
| | | break; |
| | | case 2: // OK & Mismatch |
| | | eventName = "OCR_PanelID_Read_Mismatch"; |
| | | break; |
| | | case 3: // Fail & KeyIn Match |
| | | eventName = "OCR_PanelID_Read_NG"; |
| | | break; |
| | | case 4: // Fail & KeyIn Mismatch |
| | | eventName = "OCR_PanelID_Read_NG_Mismatch"; |
| | | break; |
| | | default: |
| | | LOGE("<CHsmsPassive>Unknown VCR result=%d, fallback to OCR_PanelID_Read_OK", vcrResult); |
| | | eventName = "OCR_PanelID_Read_OK"; |
| | | break; |
| | | } |
| | | |
| | | return requestEventReportSend(eventName); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_LoadPortNotAssoc() |