#include "stdafx.h" #include "HsmsPassive.h" #include "Log.h" #include "Model.h" #include "Common.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_strSoftRev = _T("1.0.1"); m_hCimWorkThreadHandle = NULL; m_nCimWorkThrdaddr = 0; m_bCimWorking = FALSE; m_hCimWorkEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); 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; secsAreYouThereRequest(); } } }; 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 secsAreYouThereReply(pHeader->sessionId, pHeader->systemBytes); } }; 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::secsAreYouThereRequest() { 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, 0xffff, 1 | REPLY, 1, ++m_nSystemByte); ASSERT(pMessage); pAction->setSendMessage(pMessage); SetEvent(m_hCimWorkEvent); Unlock(); return ER_NOERROR; } // S1F2 int CHsmsPassive::secsAreYouThereReply(unsigned int sessionId, unsigned int systemBytes) { if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { return ER_NOTSELECT; } IMessage* pMessage = NULL; HSMS_Create1Message(pMessage, sessionId, 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; }