#include "stdafx.h" #include "HsmsPassive.h" #include "Log.h" #include "Model.h" #include "Common.h" #include char g_szAckOkData[] = { 0, 0, 0, 0 }; char g_szAckNgData[] = { 1, 0, 0, 0 }; 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::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) { 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("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("onError:%d", error); // secsIllegalData(); }; auto onRecvRawData = [&](void* pFrom, const char* pszData, int size) { LOGI("onRecvRawData:<0x%x, %d>", pszData, size); }; auto onRecvDataMessage = [&](void* pFrom, IMessage* pMessage) -> void { HEADER* pHeader = pMessage->getHeader(); int nStream = (pHeader->stream & 0x7F); LOGI("ÊÕµ½ÏûÏ¢ 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); } }; 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 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(" [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; } // 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("[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(g_szAckOkData, 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("[SECS Msg SEND]S1F14 (SysByte=%u)", pMessage->getHeader()->systemBytes); HSMS_Destroy1Message(pMessage); return 0; } // S2F31 #include #include #include #include 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); } IMessage* pMessage = NULL; HSMS_Create1Message(pMessage, m_nSessionId, 2, 32, pRecv->getHeader()->systemBytes); ASSERT(pMessage); ISECS2Item* pItem = pMessage->getBody(); pItem->setBinary(g_szAckOkData, 1, "TIACK"); m_pPassive->sendMessage(pMessage); LOGI("[SECS Msg SEND]S2F32 (SysByte=%u)", pRecv->getHeader()->systemBytes); HSMS_Destroy1Message(pMessage); return 0; }