#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>
|
|
|
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;
|
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();
|
Unlock();
|
|
if (m_hCimWorkEvent != NULL) {
|
CloseHandle(m_hCimWorkEvent);
|
m_hCimWorkEvent = NULL;
|
}
|
DeleteCriticalSection(&m_criticalSection);
|
}
|
|
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::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();
|
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);
|
m_listActionSent.erase(iter);
|
break;
|
}
|
}
|
Unlock();
|
|
if (pAction != nullptr) {
|
LOGI("onRecvMsg::ÏàÓ¦´¦Àí");
|
delete pAction;
|
}
|
|
|
return 0;
|
}
|
|
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(pHeader->systemBytes);
|
}
|
else if (nStream == 1 && pHeader->function == 13) {
|
replyEstablishCommunications(pHeader->systemBytes);
|
}
|
else if (nStream == 2 && pHeader->function == 31) {
|
replyDatetime(pMessage);
|
}
|
else if (nStream == 2 && pHeader->function == 37) {
|
replyEanbleDisableEventReport(pMessage);
|
}
|
else if (nStream == 5 && pHeader->function == 3) {
|
replyEanbleDisableAlarmReport(pMessage);
|
}
|
else if (nStream == 10 && pHeader->function == 3) {
|
replyTerminalDisplay(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::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;
|
}
|
|
return 0;
|
}
|
|
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();
|
Unlock();
|
list.pop_front();
|
TRACE("OnCimWork 004.\n");
|
|
IMessage* pMessage = pAction->getSendMessage();
|
ASSERT(pMessage);
|
m_pPassive->sendMessage(pMessage);
|
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->setEvent();
|
}
|
}
|
|
delete pAction;
|
pAction = NULL;
|
TRACE("delete m_pCurrentAction, next...\n");
|
}
|
else {
|
Lock();
|
m_listActionSent.push_back(pAction);
|
Unlock();
|
}
|
|
|
}
|
|
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(ack, 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(unsigned int systemBytes)
|
{
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
return ER_NOTSELECT;
|
}
|
|
IMessage* pMessage = NULL;
|
HSMS_Create1Message(pMessage, m_nSessionId, 1, 2, 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;
|
}
|
|
// S1F14
|
int CHsmsPassive::replyEstablishCommunications(unsigned int systemBytes)
|
{
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
return ER_NOTSELECT;
|
}
|
|
IMessage* pMessage = NULL;
|
HSMS_Create1Message(pMessage, m_nSessionId, 1, 14, systemBytes);
|
ASSERT(pMessage);
|
|
ISECS2Item* pItem = pMessage->getBody();
|
pItem->addBinaryItem(BYTE(0), "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);
|
HSMS_Destroy1Message(pMessage);
|
|
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;
|
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);
|
}
|
|
replyAck(2, 32, pRecv->getHeader()->systemBytes, BYTE(0), "TIACK");
|
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;
|
LOGI("EanbleDisableAlarm bEnable:%s", bEnable ? _T("YES") : _T("NO"));
|
for (auto item : ids) {
|
LOGI("ID:%u", item);
|
}
|
}
|
|
|
MYREPLY:
|
replyAck(2, 38, pRecv->getHeader()->systemBytes, BYTE(0), "ERACK");
|
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;
|
BYTE ALED;
|
unsigned int ALID;
|
{
|
ISECS2Item* pItem = pRecv->getBody();
|
if (pItem->getSubItemSize() < 2) goto MYREPLY;
|
if (!pItem->getSubItemBinary(0, ALED)) goto MYREPLY;
|
if (!pItem->getSubItemU4(1, ALID)) goto MYREPLY;
|
bCheckData = TRUE;
|
LOGI("EanbleDisableAlarmReport ALED:%d, ALID:%d", ALED, ALID);
|
}
|
|
|
MYREPLY:
|
replyAck(5, 4, pRecv->getHeader()->systemBytes, BYTE(0), "ACKC5");
|
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;
|
BYTE tid;
|
char* pszText = nullptr;;
|
{
|
ISECS2Item* pItem = pRecv->getBody();
|
if (pItem->getSubItemSize() < 2) goto MYREPLY;
|
if (!pItem->getSubItemBinary(0, tid)) goto MYREPLY;
|
if (!pItem->getSubItemString(1, pszText)) goto MYREPLY;
|
bCheckData = TRUE;
|
LOGI("TerminalDisplay tid:%d, pszText:%s", tid, pszText);
|
m_pModel->notifyText(RX_HSMS_TERMINAL_TEXT, pszText);
|
}
|
|
|
MYREPLY:
|
replyAck(10, 4, pRecv->getHeader()->systemBytes, BYTE(0), "ACKC10");
|
return 0;
|
}
|
|
// S5F1
|
int CHsmsPassive::requestAlarmReport(int ALCD, int ALID, const char* ALTX)
|
{
|
if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
|
return ER_NOTSELECT;
|
}
|
|
Lock();
|
CHsmsAction* pAction = new CHsmsAction(ACTION_ALARM_REPORT, TRUE, m_nActionTimeout);
|
m_listAction.push_back(pAction);
|
IMessage* pMessage = NULL;
|
HSMS_Create1Message(pMessage, m_nSessionId, 5 | REPLY, 1, ++m_nSystemByte);
|
ASSERT(pMessage);
|
ISECS2Item* pItem = pMessage->getBody();
|
pItem->addBinaryItem(BYTE(ALCD & 0xff), "ALCD");
|
pItem->addU4Item(ALID, "ALID");
|
pItem->addItem(ALTX, "ALTX");
|
pAction->setSendMessage(pMessage);
|
|
SetEvent(m_hCimWorkEvent);
|
Unlock();
|
|
return ER_NOERROR;
|
}
|