#include "stdafx.h"
|
#include "HsmsPassive.h"
|
#include "Log.h"
|
#include "Model.h"
|
#include "Common.h"
|
#include <time.h>
|
#include <iostream>
|
#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)
|
{
|
CHsmsPassive* pPassive = (CHsmsPassive*)lpParam;
|
return pPassive->OnCimWork();
|
}
|
|
CHsmsPassive* g_pPassive = NULL;
|
void CALLBACK HsmsPassiveTimerProc(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime)
|
{
|
if (g_pPassive != NULL) {
|
g_pPassive->OnTimer(nTimerid);
|
}
|
}
|
|
CHsmsPassive::CHsmsPassive()
|
{
|
m_pPassive = nullptr;
|
m_bAreYouThereRequest = FALSE;
|
m_pModel = nullptr;
|
m_nActionTimeout = 6;
|
m_nSystemByte = 0;
|
m_strEquipmentModelType = "2860";
|
m_strSoftRev = _T("1.0.1");
|
m_hCimWorkThreadHandle = NULL;
|
m_nCimWorkThrdaddr = 0;
|
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;
|
m_pActiveAction = nullptr;
|
InitializeCriticalSection(&m_criticalSection);
|
}
|
|
CHsmsPassive::~CHsmsPassive()
|
{
|
Lock();
|
for (auto item : m_listAction) {
|
delete item;
|
}
|
m_listAction.clear();
|
for (auto item : m_listActionSent) {
|
delete item;
|
}
|
m_listActionSent.clear();
|
for (auto item : m_listActionSpooling) {
|
delete item;
|
}
|
m_listActionSpooling.clear();
|
Unlock();
|
|
if (m_hCimWorkEvent != NULL) {
|
CloseHandle(m_hCimWorkEvent);
|
m_hCimWorkEvent = NULL;
|
}
|
DeleteCriticalSection(&m_criticalSection);
|
}
|
|
void CHsmsPassive::setListener(SECSListener listener)
|
{
|
m_listener = listener;
|
}
|
|
void CHsmsPassive::setActionTimeout(int nSecond)
|
{
|
m_nActionTimeout = max(3, nSecond);
|
}
|
|
void CHsmsPassive::setEquipmentModelType(const char* pszMode)
|
{
|
m_strEquipmentModelType = pszMode;
|
if (m_strEquipmentModelType.length() > 20) {
|
m_strEquipmentModelType = m_strEquipmentModelType.substr(0, 20);
|
}
|
}
|
|
void CHsmsPassive::setSoftRev(const char* pszRev)
|
{
|
m_strSoftRev = pszRev;
|
if (m_strSoftRev.length() > 20) {
|
m_strSoftRev = m_strSoftRev.substr(0, 20);
|
}
|
|
}
|
|
void CHsmsPassive::addVariableValueToItem(ISECS2Item* pParent, SERVO::CVariable* pVariable)
|
{
|
ASSERT(pParent);
|
ASSERT(pVariable);
|
|
|
ISECS2Item* pItemList;
|
SERVO::SVFromat format = pVariable->getFormat();
|
switch (format)
|
{
|
case SERVO::SVFromat::U1:
|
pParent->addU1Item((unsigned char)pVariable->getIntValue(), "SV");
|
break;
|
case SERVO::SVFromat::U2:
|
pParent->addU2Item((unsigned char)pVariable->getIntValue(), "SV");
|
break;
|
case SERVO::SVFromat::I2:
|
pParent->addI2Item((unsigned char)pVariable->getIntValue(), "SV");
|
break;
|
case SERVO::SVFromat::A20:
|
case SERVO::SVFromat::A50:
|
pParent->addItem(pVariable->getValue().c_str(), "SV");
|
break;
|
case SERVO::SVFromat::L:
|
pItemList = pParent->addItem();
|
{
|
auto vars = pVariable->getVarsValue();
|
for (auto v : vars) {
|
addVariableValueToItem(pItemList, &v);
|
}
|
}
|
break;
|
default:
|
break;
|
}
|
}
|
|
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
|
Lock();
|
for (auto iter = m_listActionSent.begin(); iter != m_listActionSent.end();) {
|
if ((*iter)->incrementAndCheckTimeout()) {
|
TRACE("CHsmsPassive::超时\n");
|
delete (*iter);
|
m_listActionSent.erase(iter++);
|
}
|
else {
|
++iter;
|
}
|
}
|
Unlock();
|
}
|
|
int CHsmsPassive::onRecvMsg(IMessage* pMessage)
|
{
|
LOGI("onRecvMsg:%s", pMessage->toString());
|
Lock();
|
if (m_pActiveAction != nullptr &&
|
(m_pActiveAction->getSendMessage()->getHeader()->systemBytes == pMessage->getHeader()->systemBytes)) {
|
SetEvent(m_pActiveAction->getEvent());
|
LOGI("CHsmsPassive::当前等待有回复");
|
TRACE("CHsmsPassive::当前等待有回复\n");
|
Unlock();
|
return 0;
|
}
|
Unlock();
|
|
|
Lock();
|
CHsmsAction* pAction = nullptr;
|
for (auto iter = m_listActionSent.begin(); iter != m_listActionSent.end(); iter++) {
|
if ((*iter)->getSendMessage()->getHeader()->systemBytes == pMessage->getHeader()->systemBytes) {
|
LOGI("CHsmsPassive::找到");
|
pAction = (*iter);
|
SetEvent(pAction->getEvent());
|
m_listActionSent.erase(iter);
|
break;
|
}
|
}
|
Unlock();
|
|
if (pAction != nullptr) {
|
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;
|
}
|
|
SERVO::CVariable* CHsmsPassive::getVariable(const char* pszName)
|
{
|
for (auto item : m_variabels) {
|
if (item->getName().compare(pszName) == 0) {
|
return item;
|
}
|
}
|
|
return nullptr;
|
}
|
|
void CHsmsPassive::clearAllVariabel()
|
{
|
for (auto item : m_variabels) {
|
delete item;
|
}
|
m_variabels.clear();
|
}
|
|
void CHsmsPassive::setVariableValue(const char* pszName, __int64 value)
|
{
|
auto v = getVariable(pszName);
|
if (v != nullptr) {
|
v->setValue(value);
|
}
|
}
|
|
void CHsmsPassive::setVariableValue(const char* pszName, const char* value)
|
{
|
auto v = getVariable(pszName);
|
if (v != nullptr) {
|
v->setValue(value);
|
}
|
}
|
|
void CHsmsPassive::setVariableValue(const char* pszName, std::vector<SERVO::CVariable>& vars)
|
{
|
auto v = getVariable(pszName);
|
if (v != nullptr) {
|
v->setValue(vars);
|
}
|
}
|
|
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)
|
{
|
m_pModel = pModel;
|
HSMS_CreatePassive(m_pPassive, pszName, port);
|
if (m_pPassive == NULL) {
|
return -1;
|
}
|
auto onStatusChanged = [&](void* pFrom, STATE state) -> void {
|
m_pModel->notifyInt(RX_CODE_PASSIVE_STATUS_CHANGED, (int)state);
|
|
// 连上之后发S1F1
|
// 修改为不主动发送,而是响应
|
/*
|
if (STATE::SELECTED == state) {
|
m_bAreYouThereRequest = FALSE;
|
if (!m_bAreYouThereRequest) {
|
m_bAreYouThereRequest = TRUE;
|
secsAreYouThereRequest();
|
}
|
}
|
*/
|
};
|
auto onRecvSysMessage = [&](void* pFrom, IMessage* pMessage) -> void {
|
LOGI("<HSMS>onRecvSysMessage:sessionId:%d, sType:%d systemBytes:%d",
|
pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes);
|
onRecvMsg(pMessage);
|
if (MSG_LINKTEST_REQ == pMessage->getHeader()->sType) {
|
/*
|
Sleep(10);
|
if (!m_bAreYouThereRequest) {
|
m_bAreYouThereRequest = TRUE;
|
requestYouThere();
|
}
|
*/
|
}
|
};
|
|
auto onError = [&](void* pFrom, int error) -> void {
|
LOGI("<HSMS>onError:%d", error);
|
// secsIllegalData();
|
};
|
|
auto onRecvRawData = [&](void* pFrom, const char* pszData, int size) {
|
LOGI("<HSMS>onRecvRawData:<0x%x, %d>", pszData, size);
|
};
|
|
auto onRecvDataMessage = [&](void* pFrom, IMessage* pMessage) -> void {
|
HEADER* pHeader = pMessage->getHeader();
|
int nStream = (pHeader->stream & 0x7F);
|
|
LOGI("<HSMS>收到消息 S%dF%d", nStream, pHeader->function);
|
if (nStream == 1 && pHeader->function == 1) {
|
// S1F1
|
replyAreYouThere(pMessage);
|
}
|
else if (nStream == 1 && pHeader->function == 3) {
|
replySelectedEquipmentStatusData(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) {
|
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 == 2 && pHeader->function == 43) {
|
replyConfigureSpooling(pMessage);
|
}
|
else if (nStream == 3 && pHeader->function == 17) {
|
replyCarrierAction(pMessage);
|
}
|
else if (nStream == 5 && pHeader->function == 3) {
|
replyEanbleDisableAlarmReport(pMessage);
|
}
|
else if (nStream == 6 && pHeader->function == 23) {
|
replyPurgeSpooledData(pMessage);
|
}
|
else if (nStream == 7 && pHeader->function == 19) {
|
replyQueryPPIDList(pMessage);
|
}
|
else if (nStream == 10 && pHeader->function == 3) {
|
replyTerminalDisplay(pMessage);
|
}
|
else if (nStream == 14 && pHeader->function == 9) {
|
replyCreateObj(pMessage);
|
}
|
else if (nStream == 16 && pHeader->function == 15) {
|
replyPRJobMultiCreate(pMessage);
|
}
|
};
|
|
PassiveListener listener;
|
listener.funStateChanged = onStatusChanged;
|
listener.funRecvRawData = onRecvRawData;
|
listener.funRecvDataMessage = onRecvDataMessage;
|
listener.funRecvSysMessage = onRecvSysMessage;
|
listener.funError = onError;
|
m_pPassive->setListener(listener);
|
|
// 启动工作线程
|
m_bCimWorking = TRUE;
|
m_hCimWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, ::CimWorkThreadFunction, this,
|
0, &m_nCimWorkThrdaddr);
|
|
g_pPassive = this;
|
SetTimer(NULL, 1, 1000, (TIMERPROC)HsmsPassiveTimerProc);
|
|
return 0;
|
}
|
|
int CHsmsPassive::loadCacheFromFile(const char* pszFilepath)
|
{
|
m_strCacheFilepath = pszFilepath;
|
|
CFile file;
|
if (!file.Open(m_strCacheFilepath.c_str(), CFile::modeRead) ) {
|
return -1;
|
}
|
|
int nBufSize = file.GetLength();
|
char* pszBuffer = new char[nBufSize];
|
file.Read(pszBuffer, nBufSize);
|
file.Close();
|
int nRet = unserialize(pszBuffer, nBufSize);
|
delete[] pszBuffer;
|
|
return nRet;
|
}
|
|
int CHsmsPassive::saveCache()
|
{
|
CFile file;
|
if (!file.Open(m_strCacheFilepath.c_str(), CFile::modeWrite | CFile::modeCreate)) {
|
return -1;
|
}
|
|
int nSize = serialize(nullptr, 0);
|
char* pszBuffer = new char[nSize];
|
int nRet = serialize(pszBuffer, nSize);
|
file.Write(pszBuffer, nSize);
|
file.Close();
|
delete[] pszBuffer;
|
|
return nRet;
|
}
|
|
int CHsmsPassive::term()
|
{
|
// 结束线程
|
m_bCimWorking = FALSE;
|
SetEvent(m_hCimWorkEvent);
|
if (m_hCimWorkThreadHandle != NULL) {
|
WaitForSingleObject(m_hCimWorkThreadHandle, INFINITE);
|
CloseHandle(m_hCimWorkThreadHandle);
|
m_hCimWorkThreadHandle = NULL;
|
}
|
|
if (m_pPassive != NULL) {
|
HSMS_DestroyPassive(m_pPassive);
|
m_pPassive = NULL;
|
}
|
|
clearAllVariabel();
|
clearAllReport();
|
clearAllCollectionEvent();
|
|
return 0;
|
}
|
|
int CHsmsPassive::serialize(char* pszBuffer, int nBufferSize)
|
{
|
int index = 0;
|
if (pszBuffer == nullptr) {
|
index += sizeof(int);
|
for (auto item : m_listActionSpooling) {
|
index += item->serialize(pszBuffer, nBufferSize);
|
}
|
|
return index;
|
}
|
else {
|
int nTemp, nRet;
|
|
nTemp = (int)m_listActionSpooling.size();
|
memcpy(&pszBuffer[index], &nTemp, sizeof(int));
|
index += sizeof(int);
|
|
for (auto item : m_listActionSpooling) {
|
nRet = item->serialize(&pszBuffer[index], nBufferSize);
|
if (nRet <= 0) break;
|
index += nRet;
|
}
|
|
return index;
|
}
|
}
|
|
int CHsmsPassive::unserialize(const char* pszBuffer, int nBufferSize)
|
{
|
int index = 0, nTemp, nRet = 0;
|
|
if (index + sizeof(int) > nBufferSize) return -1;
|
memcpy(&nTemp, &pszBuffer[index], sizeof(int));
|
index += sizeof(int);
|
|
for (int i = 0; i < nTemp; i++) {
|
CHsmsAction* pAction = new CHsmsAction();
|
nRet = pAction->unserialize(&pszBuffer[index], nBufferSize - index);
|
if (nRet <= 0) break;
|
index += nRet;
|
m_listActionSpooling.push_back(pAction);
|
}
|
|
return index + nRet;
|
}
|
|
unsigned CHsmsPassive::OnCimWork()
|
{
|
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);
|
Unlock();
|
|
while (!list.empty()) {
|
Lock();
|
CHsmsAction* pAction = list.front();
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
m_listActionSpooling.push_back(pAction);
|
Unlock();
|
continue;
|
}
|
Unlock();
|
list.pop_front();
|
TRACE("OnCimWork 004.\n");
|
|
if (pAction->isNeedWaitReply()) {
|
// 如果需要等待回复
|
Lock();
|
m_pActiveAction = pAction;
|
IMessage* pMessage = pAction->getSendMessage();
|
Unlock();
|
|
ASSERT(pMessage);
|
m_pPassive->sendMessage(pMessage);
|
LOGI("<HSMS> [SEND] SysByte=%u sessionId:%d", pMessage->getHeader()->systemBytes, pMessage->getHeader()->sessionId);
|
|
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->setEvent();
|
}
|
}
|
Lock();
|
delete m_pActiveAction;
|
m_pActiveAction = nullptr;
|
Unlock();
|
}
|
else {
|
Lock();
|
m_listActionSent.push_back(pAction);
|
IMessage* pMessage = pAction->getSendMessage();
|
Unlock();
|
|
ASSERT(pMessage);
|
m_pPassive->sendMessage(pMessage);
|
LOGI("<HSMS> [SEND] SysByte=%u sessionId:%d", pMessage->getHeader()->systemBytes, pMessage->getHeader()->sessionId);
|
|
}
|
}
|
|
TRACE("OnCimWork \n");
|
}
|
|
// _endthreadex(0);
|
TRACE("OnCimWork exit\n");
|
return 0;
|
}
|
|
// 通用的reply ack函数
|
void CHsmsPassive::replyAck(int s, int f, unsigned int systemBytes, BYTE ack, const char* pszAckName)
|
{
|
IMessage* pMessage = NULL;
|
HSMS_Create1Message(pMessage, m_nSessionId, s, f, systemBytes);
|
ASSERT(pMessage);
|
ISECS2Item* pItem = pMessage->getBody();
|
pItem->setBinary((const char*)&ack, 1, pszAckName);
|
m_pPassive->sendMessage(pMessage);
|
LOGI("<HSMS>[SECS Msg SEND]S%dF%d (SysByte=%u)", s, f, systemBytes);
|
HSMS_Destroy1Message(pMessage);
|
}
|
|
// S1F1
|
int CHsmsPassive::requestAreYouThere()
|
{
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
return ER_NOTSELECT;
|
}
|
|
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);
|
pAction->setSendMessage(pMessage);
|
|
SetEvent(m_hCimWorkEvent);
|
Unlock();
|
|
|
return ER_NOERROR;
|
}
|
|
// S1F2
|
int CHsmsPassive::replyAreYouThere(IMessage* pRecv)
|
{
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
return ER_NOTSELECT;
|
}
|
|
IMessage* pMessage = NULL;
|
HSMS_Create1Message(pMessage, m_nSessionId, 1, 2, pRecv->getHeader()->systemBytes);
|
ASSERT(pMessage);
|
|
ISECS2Item* pItem = pMessage->getBody();
|
pItem->addItem(m_strEquipmentModelType.c_str(), "MDLN");
|
pItem->addItem(m_strSoftRev.c_str(), "SOFTREV");
|
m_pPassive->sendMessage(pMessage);
|
LOGI("<HSMS>[SECS Msg SEND]S1F2 (SysByte=%u)", pMessage->getHeader()->systemBytes);
|
HSMS_Destroy1Message(pMessage);
|
|
return 0;
|
}
|
|
// 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;
|
}
|
|
// S1F13
|
int CHsmsPassive::replyEstablishCommunications(IMessage* pRecv)
|
{
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
return ER_NOTSELECT;
|
}
|
|
IMessage* pMessage = NULL;
|
HSMS_Create1Message(pMessage, m_nSessionId, 1, 14, pRecv->getHeader()->systemBytes);
|
ASSERT(pMessage);
|
|
ISECS2Item* pItem = pMessage->getBody();
|
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]%s", pMessage->toString());
|
HSMS_Destroy1Message(pMessage);
|
|
return 0;
|
}
|
|
// S1F3
|
int CHsmsPassive::replySelectedEquipmentStatusData(IMessage* pRecv)
|
{
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
return ER_NOTSELECT;
|
}
|
|
IMessage* pMessage = NULL;
|
HSMS_Create1Message(pMessage, m_nSessionId, 1, 4, pRecv->getHeader()->systemBytes);
|
ASSERT(pMessage);
|
|
unsigned char SVU1 = 0;
|
unsigned int SVID = 0;
|
ISECS2Item* pBody = pRecv->getBody();
|
if (pBody == nullptr || pBody->getType() != SITYPE::L) {
|
pMessage->getBody()->addU1Item(SVU1, "SV");
|
goto MYREPLY;
|
}
|
if (!pBody->getSubItemU4(0, SVID)) {
|
pMessage->getBody()->addU1Item(SVU1, "SV");
|
goto MYREPLY;
|
}
|
|
SERVO::CVariable* pVariable = getVariable(SVID);
|
if (pVariable == nullptr) {
|
pMessage->getBody()->addU1Item(SVU1, "SV");
|
goto MYREPLY;
|
}
|
addVariableValueToItem(pMessage->getBody(), pVariable);
|
|
MYREPLY:
|
m_pPassive->sendMessage(pMessage);
|
LOGI("<HSMS>[SECS Msg SEND]%s", pMessage->toString());
|
HSMS_Destroy1Message(pMessage);
|
|
|
|
return 0;
|
}
|
|
// S2F13
|
int CHsmsPassive::replyEquipmentConstantRequest(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++) {
|
EQConstant eqc;
|
unsigned short id;
|
if (pItem->getSubItemU2(i, id)) {
|
eqc.id = id;
|
eqcs.push_back(eqc);
|
}
|
}
|
}
|
|
|
// 交由上层应用来获取机器常量值
|
if (m_listener.onEQConstantRequest != nullptr) {
|
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 : 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;
|
}
|
|
// S2F31
|
int CHsmsPassive::replyDatetime(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;
|
const char* pszMessage;
|
if (pBody->getString(pszMessage)) {
|
// 更新时间
|
SYSTEMTIME time;
|
char szBuffer[20];
|
memcpy(szBuffer, pszMessage, 16);
|
szBuffer[14] = '\0';
|
time.wSecond = atoi(&szBuffer[12]);
|
szBuffer[12] = '\0';
|
time.wMinute = atoi(&szBuffer[10]);
|
szBuffer[10] = '\0';
|
time.wHour = atoi(&szBuffer[8]);
|
szBuffer[8] = '\0';
|
time.wDay = atoi(&szBuffer[6]);
|
szBuffer[6] = '\0';
|
time.wMonth = atoi(&szBuffer[4]);
|
szBuffer[4] = '\0';
|
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->getFirstPortID());
|
}
|
|
MYREPLY:
|
replyAck(2, 36, pRecv->getHeader()->systemBytes, BYTE(0), "LRACK");
|
return 0;
|
}
|
|
// S2F37
|
int CHsmsPassive::replyEanbleDisableEventReport(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;
|
bool bEnable;
|
std::vector<unsigned int> ids;
|
{
|
ISECS2Item* pItemIds;
|
ISECS2Item* pItem = pRecv->getBody();
|
if (pItem->getSubItemSize() < 2) goto MYREPLY;
|
if (!pItem->getSubItemBool(0, bEnable)) goto MYREPLY;
|
pItemIds = pItem->getSubItem(1);
|
if (pItemIds == nullptr || pItemIds->getType() != SITYPE::L) goto MYREPLY;
|
for (int i = 0; i < pItemIds->getSubItemSize(); i++) {
|
unsigned int id;
|
if (pItemIds->getSubItemU4(i, id)) {
|
ids.push_back(id);
|
}
|
}
|
bCheckData = TRUE;
|
if (m_listener.onEnableDisableEventReport != nullptr) {
|
m_listener.onEnableDisableEventReport(this, bEnable, ids);
|
}
|
}
|
|
|
MYREPLY:
|
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;
|
}
|
|
// S2F43
|
int CHsmsPassive::replyConfigureSpooling(IMessage* pRecv)
|
{
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
return ER_NOTSELECT;
|
}
|
ISECS2Item* pBody = pRecv->getBody();
|
if (pBody == nullptr || pBody->getType() != SITYPE::L) ER_PARAM_ERROR;
|
|
// 清空所有
|
if (pBody->getSubItemSize() == 0) {
|
m_spoolingConfig.clear();
|
goto MYREPLY;
|
}
|
|
// 依次配置Stream
|
for (int i = 0; i < pBody->getSubItemSize(); i++) {
|
ISECS2Item* pStreamItem = pBody->getSubItem(i);
|
ASSERT(pStreamItem);
|
unsigned char STRID, FCNID;
|
pStreamItem->getSubItemU1(0, STRID);
|
ISECS2Item* pFcnItemList = pStreamItem->getSubItem(1);
|
if (pFcnItemList->getSubItemSize() == 0) {
|
m_spoolingConfig[STRID].clear();
|
}
|
else {
|
for (int j = 0; j < pFcnItemList->getSubItemSize(); j++) {
|
pFcnItemList->getSubItemU1(j, FCNID);
|
m_spoolingConfig[STRID].insert(FCNID);
|
}
|
}
|
}
|
|
// 打印验证结果
|
for (auto s : m_spoolingConfig) {
|
LOGI("====> stream:%d", s.first);
|
for (auto f : s.second) {
|
LOGI("function:%d", f);
|
}
|
}
|
MYREPLY:
|
replyAck(2, 42, pRecv->getHeader()->systemBytes, BYTE(0), "ERACK");
|
return 0;
|
}
|
|
// S3F17
|
int CHsmsPassive::replyCarrierAction(IMessage* pRecv)
|
{
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
return ER_NOTSELECT;
|
}
|
|
unsigned char CAACK = CAACK_0;
|
unsigned int ERRCODE = 0;
|
std::string strError = "no error";
|
if (m_listener.onCarrierAction == nullptr) {
|
CAACK = 5;
|
ERRCODE = CAACK_5;
|
strError = "Not supported";
|
goto MYREPLY;
|
}
|
|
|
ISECS2Item* pBody = pRecv->getBody();
|
if (pBody == nullptr || pBody->getType() != SITYPE::L) ER_PARAM_ERROR;
|
|
unsigned int DATAID;
|
unsigned char PTN;
|
const char* pszCarrierAction, *pszCarrierId;
|
pBody->getSubItemU4(0, DATAID);
|
pBody->getSubItemString(1, pszCarrierAction);
|
pBody->getSubItemString(2, pszCarrierId);
|
pBody->getSubItemU1(3, PTN);
|
ERRCODE = m_listener.onCarrierAction(this,
|
DATAID,
|
pszCarrierAction,
|
pszCarrierId,
|
PTN,
|
strError);
|
CAACK = ERRCODE;
|
|
// 回复
|
MYREPLY:
|
IMessage* pMessage = NULL;
|
HSMS_Create1Message(pMessage, m_nSessionId, 3, 18, pRecv->getHeader()->systemBytes);
|
pMessage->getBody()->addU1Item(CAACK, "CAACK");
|
ISECS2Item* pErrItem = pMessage->getBody()->addItem();
|
pErrItem->addU4Item(ERRCODE, "ERRCODE");
|
pErrItem->addItem(strError.c_str(), "ERRTEXT");
|
m_pPassive->sendMessage(pMessage);
|
LOGI("<HSMS>[SECS Msg SEND]S3F18 (SysByte=%u)", pMessage->getHeader()->systemBytes);
|
HSMS_Destroy1Message(pMessage);
|
|
return 0;
|
}
|
|
// S5F3
|
int CHsmsPassive::replyEanbleDisableAlarmReport(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* ALED;
|
unsigned int ALID;
|
unsigned int ALEDLEN;
|
{
|
ISECS2Item* pItem = pRecv->getBody();
|
if (pItem->getSubItemSize() < 2) goto MYREPLY;
|
if (!pItem->getSubItemBinary(0, ALED, ALEDLEN)) goto MYREPLY;
|
if (!pItem->getSubItemU4(1, ALID)) goto MYREPLY;
|
bCheckData = TRUE;
|
LOGI("EanbleDisableAlarmReport ALED:0x%02x, ALID:%d", ALED[0], ALID);
|
if (m_listener.onEnableDisableAlarmReport != nullptr) {
|
m_listener.onEnableDisableAlarmReport(this, ALED[0] != 0, ALID);
|
}
|
}
|
|
|
MYREPLY:
|
replyAck(5, 4, pRecv->getHeader()->systemBytes, BYTE(0), "ACKC5");
|
return 0;
|
}
|
|
// S6F23
|
int CHsmsPassive::replyPurgeSpooledData(IMessage* pRecv)
|
{
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
return ER_NOTSELECT;
|
}
|
ISECS2Item* pBody = pRecv->getBody();
|
if (pBody == nullptr || pBody->getType() != SITYPE::U1) ER_PARAM_ERROR;
|
unsigned char RSDC; // 0 - transmit; 1 - purge;
|
pBody->getU1(RSDC);
|
if (RSDC != 0 && RSDC != 1) ER_PARAM_ERROR;
|
|
BYTE ACK = 0; // 0 - ok; 1 - retryable busy; 2 - no spool data;
|
if (m_listActionSpooling.empty()) {
|
ACK = 2;
|
}
|
replyAck(6, 24, pRecv->getHeader()->systemBytes, ACK, "RSDA");
|
|
|
// 丢弃
|
if (RSDC == 1) {
|
Lock();
|
for (auto item : m_listActionSpooling) {
|
delete item;
|
}
|
m_listActionSpooling.clear();
|
Unlock();
|
}
|
else {
|
Lock();
|
for (auto item : m_listActionSpooling) {
|
m_listAction.push_back(item);
|
}
|
m_listActionSpooling.clear();
|
Unlock();
|
SetEvent(m_hCimWorkEvent);
|
}
|
|
return 0;
|
}
|
|
// S7F19
|
int CHsmsPassive::replyQueryPPIDList(IMessage* pRecv)
|
{
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
return ER_NOTSELECT;
|
}
|
if (m_listener.onQueryPPIDList == nullptr) {
|
return ER_NO_PPID_LIST;
|
}
|
|
IMessage* pMessage = NULL;
|
HSMS_Create1Message(pMessage, m_nSessionId, 7, 20, pRecv->getHeader()->systemBytes);
|
ASSERT(pMessage);
|
|
ISECS2Item* pItem = pMessage->getBody();
|
auto ppids = m_listener.onQueryPPIDList(this);
|
for (auto item : ppids) {
|
pItem->addItem(item.c_str(), "PPID");
|
}
|
|
m_pPassive->sendMessage(pMessage);
|
LOGI("<HSMS>[SECS Msg SEND]S7F20 (SysByte=%u)", pMessage->getHeader()->systemBytes);
|
HSMS_Destroy1Message(pMessage);
|
|
return 0;
|
}
|
|
// S10F3
|
int CHsmsPassive::replyTerminalDisplay(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* tid;
|
unsigned int tidlen;
|
const char* pszText = nullptr;;
|
{
|
ISECS2Item* pItem = pRecv->getBody();
|
if (pItem->getSubItemSize() < 2) goto MYREPLY;
|
if (!pItem->getSubItemBinary(0, tid, tidlen)) goto MYREPLY;
|
if (!pItem->getSubItemString(1, pszText)) goto MYREPLY;
|
bCheckData = TRUE;
|
LOGI("TerminalDisplay tid:0x%02x, pszText:%s", tid[0], pszText);
|
m_pModel->notifyText(RX_HSMS_TERMINAL_TEXT, pszText);
|
}
|
|
|
MYREPLY:
|
replyAck(10, 4, pRecv->getHeader()->systemBytes, BYTE(0), "ACKC10");
|
return 0;
|
}
|
|
// S14F9
|
int CHsmsPassive::replyCreateObj(IMessage* pRecv)
|
{
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
return ER_NOTSELECT;
|
}
|
ISECS2Item* pBody = pRecv->getBody();
|
if (pBody == nullptr || pBody->getType() != SITYPE::L) ER_PARAM_ERROR;
|
|
|
// 是否创建成功并准备回复报文
|
bool bCreateOk = false;
|
IMessage* pReply = NULL;
|
HSMS_Create1Message(pReply, m_nSessionId, 14, 10, ++m_nSystemByte);
|
ASSERT(pReply);
|
|
|
|
// 解释数据,得到ControlJob
|
ISECS2Item* pItemAttrs, * pItemAttr, *pItemAttrData;
|
const char* pszObjSpec, *pszObjType, *pszAttrId, *pszProcessJobId;
|
std::string strObjName, strObjId;
|
if (!pBody->getSubItemString(0, pszObjSpec)) return ER_PARAM_ERROR;
|
if (!pBody->getSubItemString(1, pszObjType)) return ER_PARAM_ERROR;
|
|
pReply->getBody()->addItem(pszObjSpec, "OBJSPEC");
|
ISECS2Item* pReplyItemAttrs = pReply->getBody()->addItem();
|
ISECS2Item* pReplyItemAcks = pReply->getBody()->addItem();
|
ISECS2Item* pReplyItemAck = pReplyItemAcks->addU1Item(0, "OBJACK");
|
ISECS2Item* pReplyItemErrs = pReplyItemAcks->addItem();
|
|
// 当前只处理类各为ControlJob
|
if (_strcmpi(pszObjType, "ControlJob") == 0) {
|
|
// 类id
|
std::regex re("^([^:]+):([^>]+)>");
|
std::smatch match;
|
std::string strObjSpec(pszObjSpec);
|
if (!std::regex_search(strObjSpec, match, re)) {
|
ISECS2Item* pItemError = pReplyItemErrs->addItem();
|
pItemError->addU4Item(2001, "ERRCODE");
|
pItemError->addItem("参数或报文不正确", "ERRTEXT");
|
goto MYREPLY;
|
}
|
|
if (match[1].compare("ControlJob") != 0) {
|
ISECS2Item* pItemError = pReplyItemErrs->addItem();
|
pItemError->addU4Item(2001, "ERRCODE");
|
pItemError->addItem("不支持的OBJ", "ERRTEXT");
|
goto MYREPLY;
|
}
|
strObjId = match[2];
|
|
// 创建类CControlJob
|
SERVO::CControlJob controlJob(strObjId);
|
|
// 类属性
|
pItemAttrs = pBody->getSubItem(2);
|
if (pItemAttrs == nullptr) return ER_PARAM_ERROR;
|
for (int i = 0; i < pItemAttrs->getSubItemSize(); i++) {
|
pItemAttr = pItemAttrs->getSubItem(i);
|
if (pItemAttr == nullptr) continue;
|
if (!pItemAttr->getSubItemString(0, pszAttrId)) continue;
|
if (_strcmpi(pszAttrId, CJ_ATTR_PRIORITY) == 0) {
|
uint8_t priority;
|
if (pItemAttr->getSubItemU1(1, priority)) {
|
controlJob.setPriority(priority);
|
}
|
}
|
else if (_strcmpi(pszAttrId, CJ_ATTR_PRJOBLIST) == 0) {
|
pItemAttrData = pItemAttr->getSubItem(1);
|
if (pItemAttrData != nullptr && pItemAttrData->getType() == SITYPE::L) {
|
for (int i = 0; i < pItemAttrData->getSubItemSize(); i++) {
|
if (pItemAttrData->getSubItemString(i, pszProcessJobId)) {
|
std::string strProcessJobId(pszProcessJobId);
|
controlJob.addPJ(strProcessJobId);
|
}
|
}
|
}
|
}
|
}
|
|
|
ASSERT(m_listener.onControlJobCreate != nullptr);
|
int nRet = m_listener.onControlJobCreate(this, controlJob);
|
bCreateOk = nRet == 0;
|
|
// 添加新建类的各种属性到回复报文中
|
if(bCreateOk) {
|
{
|
ISECS2Item* pReplyItemAttr = pReplyItemAttrs->addItem();
|
pReplyItemAttr->addItem(CJ_ATTR_PRIORITY, "ATTRID");
|
pReplyItemAttr->addU1Item(controlJob.priority(), "ATTRDATA");
|
}
|
|
{
|
ISECS2Item* pReplyItemAttr = pReplyItemAttrs->addItem();
|
pReplyItemAttr->addItem(CJ_ATTR_PRJOBLIST, "ATTRID");
|
ISECS2Item* pItemPjs = pReplyItemAttr->addItem();
|
auto pjIds = controlJob.pjIds();
|
for (auto id : pjIds) {
|
pItemPjs->addItem(id.c_str(), "PRJOBID");
|
}
|
}
|
}
|
else {
|
auto issues = controlJob.issues();
|
for (auto i : issues) {
|
ISECS2Item* pItemError = pReplyItemErrs->addItem();
|
pItemError->addU4Item(i.code, "ERRCODE");
|
pItemError->addItem(i.text.c_str(), "ERRTEXT");
|
}
|
}
|
}
|
|
|
else {
|
ISECS2Item* pItemError = pReplyItemErrs->addItem();
|
pItemError->addU4Item(2001, "ERRCODE");
|
pItemError->addItem("不支持的OBJ", "ERRTEXT");
|
}
|
|
|
// 完善报文并回复
|
MYREPLY:
|
pReplyItemAck->setU1(bCreateOk ? 0 : 1, "OBJACK");
|
m_pPassive->sendMessage(pReply);
|
LOGI("<HSMS>[SECS Msg SEND]S14F10 (SysByte=%u)", pReply->getHeader()->systemBytes);
|
HSMS_Destroy1Message(pReply);
|
|
|
return 0;
|
}
|
|
// S16F15
|
int CHsmsPassive::replyPRJobMultiCreate(IMessage* pRecv)
|
{
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
return ER_NOTSELECT;
|
}
|
ISECS2Item* pBody = pRecv->getBody();
|
if (pBody == nullptr || pBody->getType() != SITYPE::L) ER_PARAM_ERROR;
|
|
|
// 解释数据,得到CProcessJob
|
ISECS2Item* pItemPjs, * pItemPj,* pItemCarriers, * pItemCarrier, *pItemSlots, *pItemRecipes;
|
unsigned int DATAID;
|
const char* pszPrjobid, *pszMF, *pszCarrierId, *pszRecipeName;
|
std::string strCarrierId;
|
unsigned int len;
|
unsigned char slot, PRRECIPEMETHOD;
|
std::vector<unsigned char> slots;
|
std::vector<SERVO::CProcessJob*> pjs;
|
|
if (!pBody->getSubItemU4(0, DATAID)) return ER_PARAM_ERROR;
|
pItemPjs = pBody->getSubItem(1);
|
if (pItemPjs == nullptr) return ER_PARAM_ERROR;
|
for (int i = 0; i < pItemPjs->getSubItemSize(); i++) {
|
pItemPj = pItemPjs->getSubItem(i);
|
if (pItemPj == nullptr) continue;
|
if (!pItemPj->getSubItemString(0, pszPrjobid)) continue;
|
if (!pItemPj->getSubItemBinary(1, pszMF, len)) continue;
|
pItemCarriers = pItemPj->getSubItem(2);
|
if (pItemCarriers == nullptr) continue;
|
pItemRecipes = pItemPj->getSubItem(3);
|
if (pItemRecipes == nullptr) continue;
|
SERVO::CProcessJob* pj = new SERVO::CProcessJob(pszPrjobid);
|
int size = pItemCarriers->getSubItemSize();
|
for (int j = 0; j < size; j++) {
|
pItemCarrier = pItemCarriers->getSubItem(j);
|
strCarrierId.clear();
|
if (pItemCarrier->getSubItemString(0, pszCarrierId)) {
|
strCarrierId = pszCarrierId;
|
}
|
|
slots.clear();
|
pItemSlots = pItemCarrier->getSubItem(1);
|
if (pItemSlots != nullptr) {
|
int size2 = pItemSlots->getSubItemSize();
|
for (int k = 0; k < size2; k++) {
|
if (pItemSlots->getSubItemU1(k, slot)) {
|
slots.push_back(slot);
|
}
|
}
|
}
|
pj->addCarrier(strCarrierId, slots);
|
}
|
if (pItemRecipes->getSubItemU1(0, PRRECIPEMETHOD)
|
&& pItemRecipes->getSubItemString(1, pszRecipeName)) {
|
pj->setRecipe(SERVO::RecipeMethod(PRRECIPEMETHOD), std::string(pszRecipeName));
|
}
|
|
pjs.push_back(pj);
|
}
|
|
ASSERT(m_listener.onPRJobMultiCreate != nullptr);
|
int nRet = m_listener.onPRJobMultiCreate(this, pjs);
|
|
|
// 回复报文
|
IMessage* pMessage = NULL;
|
HSMS_Create1Message(pMessage, m_nSessionId, 16, 16, ++m_nSystemByte);
|
ASSERT(pMessage);
|
ISECS2Item* pItemPrjobIds = pMessage->getBody()->addItem();
|
ISECS2Item* pItemErrors = pMessage->getBody()->addItem();
|
bool bHasError = false;
|
for (auto p : pjs) {
|
if (p->issues().empty()) {
|
pItemPrjobIds->addItem(p->id().c_str(), "PRJOBID");
|
}
|
else {
|
bHasError = true;
|
}
|
}
|
if (bHasError) {
|
pItemErrors->addBoolItem(false, "ACKA");
|
ISECS2Item* pItemErrors2 = pItemErrors->addItem();
|
for (auto p : pjs) {
|
if (!p->issues().empty()) {
|
ISECS2Item* pItemErr = pItemErrors2->addItem();
|
pItemErr->addU4Item(p->issues()[0].code, "ERRCODE");
|
pItemErr->addItem(("<" + p->id() + ">" + p->issues()[0].text).c_str(), "ERRTEXT");
|
}
|
}
|
}
|
m_pPassive->sendMessage(pMessage);
|
LOGI("<HSMS>[SECS Msg SEND]S16F16 (SysByte=%u)", pMessage->getHeader()->systemBytes);
|
HSMS_Destroy1Message(pMessage);
|
|
|
// 释放有问题(未添加到master)的内存
|
for (auto p : pjs) {
|
if(!p->issues().empty()) delete p;
|
}
|
pjs.clear();
|
|
return 0;
|
}
|
|
// S5F1
|
int CHsmsPassive::requestAlarmReport(int ALCD, int ALID, const char* ALTX)
|
{
|
char szALCD[1];
|
szALCD[0] = ALCD & 0xff;
|
|
Lock();
|
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);
|
ISECS2Item* pItem = pMessage->getBody();
|
pItem->addBinaryItem(szALCD, 1, "ALCD");
|
pItem->addU4Item(ALID, "ALID");
|
pItem->addItem(ALTX, "ALTX");
|
pAction->setSendMessage(pMessage);
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
m_listActionSpooling.push_back(pAction);
|
}
|
else {
|
m_listAction.push_back(pAction);
|
SetEvent(m_hCimWorkEvent);
|
}
|
Unlock();
|
|
return ER_NOERROR;
|
}
|
|
// S6F11
|
static unsigned int DATAID = 1;
|
int CHsmsPassive::requestEventReportSend(unsigned int CEID)
|
{
|
SERVO::CCollectionEvent* pEvent = getEvent(CEID);
|
if (pEvent == nullptr) {
|
return ER_NO_EVENT;
|
}
|
|
SERVO::CReport* pReport = pEvent->getFirstReport();
|
if (pReport == nullptr) {
|
return ER_UNLINK_EVENT_REPORT;
|
}
|
|
|
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);
|
ISECS2Item* pItem = pMessage->getBody();
|
pItem->addU4Item(++DATAID, "DATAID");
|
pItem->addU4Item(CEID, "CEID");
|
ISECS2Item* pItemList1 = pItem->addItem();
|
ISECS2Item* pItemList2 = pItemList1->addItem();
|
pItemList2->addU4Item(pReport->getReportId(), "RPTID");
|
ISECS2Item* pItemList3 = pItemList2->addItem();
|
|
auto vars = pReport->getVariables();
|
for (auto var : vars) {
|
addVariableValueToItem(pItemList3, var);
|
}
|
pAction->setSendMessage(pMessage);
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
m_listActionSpooling.push_back(pAction);
|
}
|
else {
|
m_listAction.push_back(pAction);
|
SetEvent(m_hCimWorkEvent);
|
}
|
Unlock();
|
|
return ER_NOERROR;
|
}
|
|
int CHsmsPassive::requestEventReportSend(const char* pszEventName)
|
{
|
SERVO::CCollectionEvent* pEvent = nullptr;
|
for (auto e : m_collectionEvents) {
|
if (e->getName().compare(pszEventName) == 0) {
|
pEvent = e;
|
break;
|
}
|
}
|
if (pEvent == nullptr) {
|
return ER_NO_EVENT;
|
}
|
return requestEventReportSend(pEvent->getEventId());
|
}
|
|
int CHsmsPassive::requestEventReportSend_CarrierID_Readed()
|
{
|
return requestEventReportSend("CarrierID_Readed");
|
}
|
|
int CHsmsPassive::requestEventReportSend_PJ_Queued()
|
{
|
return requestEventReportSend("PJ_Queued");
|
}
|
|
int CHsmsPassive::requestEventReportSend_PJ_Start()
|
{
|
return requestEventReportSend("PJ_Start");
|
}
|
|
int CHsmsPassive::requestEventReportSend_PJ_End()
|
{
|
return requestEventReportSend("PJ_End");
|
}
|
|
int CHsmsPassive::requestEventReportSend_CJ_Start()
|
{
|
return requestEventReportSend("CJ_Start");
|
}
|
|
int CHsmsPassive::requestEventReportSend_CJ_End()
|
{
|
return requestEventReportSend("CJ_End");
|
}
|
|
int CHsmsPassive::requestEventReportSend_Panel_Start()
|
{
|
return requestEventReportSend("Panel_Start");
|
}
|
|
int CHsmsPassive::requestEventReportSend_Panel_End()
|
{
|
return requestEventReportSend("Panel_End");
|
}
|