#include "stdafx.h" #include "DeliverModule.h" #include CDeliverModule::CDeliverModule(WriteLog* logFun) { m_SdcCommondvector.clear(); m_CommondType.clear(); m_hSendingThreadToggleEvent=NULL; m_bSendingCommandsThreadExit = false; m_SendingCommandsThread=NULL; m_hACKEvent=NULL; m_nAKRsubmit=0; m_bisNAK=false; m_hCPEvent=NULL; m_nCPRsubmit=0; m_bisNCP=false; m_ClientControl = NULL; m_pSendData=NULL; m_pLogFun = logFun; m_bIsGenErr=false; m_nAKResendTotalNum=3; m_nCPResendTotalNum=1; } CDeliverModule::~CDeliverModule(void) { } ///////////////////// //设备初始化的时候要把等待AK的事件设置为手动激活 //m_hACKEvent=CreateEvent(NULL, TRUE, FALSE, NULL); //并建立发送线程 //StartSendingCommandsThread(this); /////////////////// ///////////////////// //退出的时候也要调用函数结束掉发送线程 //StopSendingCommandsThread(); //////////////////// void CDeliverModule::SetPriority(int nCommandType,bool IsWaitforACK,int WaitingTime,bool IsResend,bool IsClearSendVector,bool IsFirstSend,bool IsWaitforCP,int WatingCPtime,bool isClearSamePriority) { tagCommandTye proiority; proiority.nCommandType=nCommandType; proiority.IsWaitforACK=IsWaitforACK; proiority.WaitingTime=WaitingTime; proiority.IsResend=IsResend; proiority.IsClearSendVector=IsClearSendVector; proiority.IsFirstSend=IsFirstSend; proiority.IsWaitforCP=IsWaitforCP; proiority.WatingCPtime=WatingCPtime; proiority.isClearSamePriority=isClearSamePriority; m_CommondType.push_back(proiority); } void CDeliverModule::SetGenErrStatus(bool isGenErr) { m_bIsGenErr=isGenErr; } bool CDeliverModule::SetLogFun(WriteLog* logFun) { if(logFun != NULL) { m_pLogFun = logFun; return true; } return false; } bool CDeliverModule::InitSendModle(SendCommands* pSendData,void* lparam) { m_ClientControl = lparam; m_pSendData = pSendData; //设备初始化的时候要把等待AK的事件设置为手动激活 m_hACKEvent=CreateEvent(NULL, TRUE, FALSE, NULL); m_hCPEvent=CreateEvent(NULL, TRUE, FALSE, NULL); //并建立发送线程 StartSendingCommandsThread(this); return true; } void CDeliverModule::EixtSendModle() { StopSendingCommandsThread(); m_ClientControl = NULL; m_pSendData=NULL; m_SdcCommondvector.clear(); m_CommondType.clear(); } DWORD CDeliverModule::SendingCommandsThread(LPVOID pParam) { CDeliverModule* pCurrentGen = (CDeliverModule*) pParam; if (pCurrentGen == NULL) { if (pCurrentGen->m_pLogFun) { pCurrentGen->m_pLogFun("The pCurrentGen is NULL", LOG_V2_ERROR); } return 0; } DWORD event = 0; BOOL bExit = false; //indicating start thread success; SetEvent(pCurrentGen->m_hSendingThreadToggleEvent); //perform sending sedecal commands while (!pCurrentGen->m_bSendingCommandsThreadExit) { //query the command from the vector tagCommandStruct tempCommand; tempCommand.strCommand = ""; tempCommand.nCommmandType = 0; if (pCurrentGen->m_SdcCommondvector.size() > 0) { std::unique_lock uqeSection(pCurrentGen->m_iCriticalSection); tempCommand.nCommmandType = pCurrentGen->m_SdcCommondvector[0].nCommmandType; tempCommand.strCommand = pCurrentGen->m_SdcCommondvector[0].strCommand; pCurrentGen->m_SdcCommondvector.erase(pCurrentGen->m_SdcCommondvector.begin());//erase the first command uqeSection.unlock(); if (tempCommand.strCommand != "")// with commnad { pCurrentGen->SendCommand(tempCommand.strCommand,tempCommand.nCommmandType); Sleep(50); } else { Sleep(10);//no commnad to send, so sleep 10 ms } // send command } else { Sleep(10); } } //indicating the end of thread; SetEvent(pCurrentGen->m_hSendingThreadToggleEvent); return 0; } //start timer to do offset calibration periodically; bool CDeliverModule::StartSendingCommandsThread(CDeliverModule* pCurrentGen) { //create thread; DWORD m_HardwareStatusID; m_SendingCommandsThread = CreateThread(0, 0, SendingCommandsThread, this, 0, &m_HardwareStatusID); if (NULL == m_SendingCommandsThread) { if (m_pLogFun) { m_pLogFun("Create sending commands thread failed!", LOG_V2_ERROR); } return false; } //wait till thread create successful; if (WaitForSingleObject(pCurrentGen->m_hSendingThreadToggleEvent,5000) == WAIT_OBJECT_0) { if (m_pLogFun) { m_pLogFun("detected the start of sending commands thread!", LOG_V2_INFO); } ResetEvent(pCurrentGen->m_hSendingThreadToggleEvent); } m_nSendingCommandsThreadId = m_HardwareStatusID; return true; } //stop sending commands thread periodically; void CDeliverModule::StopSendingCommandsThread() { if (m_pLogFun) { m_pLogFun("sending commands thread exiting...", LOG_V2_WARNING); } if (NULL != m_SendingCommandsThread) { m_bSendingCommandsThreadExit = true; if (::WaitForSingleObject(m_hSendingThreadToggleEvent,5000)==WAIT_OBJECT_0) { if (m_pLogFun) { m_pLogFun("detected the exit of sending commands thread!", LOG_V2_INFO); } ResetEvent(m_hSendingThreadToggleEvent); } else { DWORD exitCode = 0; //Retrieves the termination status of the specified thread; if (!GetExitCodeThread(m_SendingCommandsThread, &exitCode)) { DWORD nError = ::GetLastError(); std::string logstr; if (m_pLogFun) { logstr = std::format("GetExitCodeThread() error, error No is {:d}", nError); m_pLogFun(logstr.c_str(), LOG_V2_ERROR); } } TerminateThread(m_SendingCommandsThread,exitCode); } m_SendingCommandsThread = NULL; } } /* strCommand which will be send to gen side nType commnad type 0, no ACK , 1, with ACK, 2, apr command, 3, focus?(to be confirmed) */ bool CDeliverModule::ProcessCommand(std::string strCommand,int nType) { std::unique_lock uqeSection(m_iCriticalSection); m_SDCCommand.strCommand = strCommand; m_SDCCommand.nCommmandType = nType; /*std::string logstr; logstr = "strcommand is " + m_SDCCommand.strCommand; m_pGen->logfile->WriteLog(logstr,LOG_INFORMATION,LOG_DEBUG,true); logstr.Format("CommmandType is %d",nType); m_pGen->logfile->WriteLog(logstr,LOG_INFORMATION,LOG_DEBUG,true);*/ int i=0; for (i=0;ilogfile->WriteLog(logstr,LOG_INFORMATION,LOG_DEBUG,true);*/ break; } } if (i==m_CommondType.size()) { uqeSection.unlock(); return false; } std::string logstr; for(int j=0;j uqeSection(m_iCriticalSection); m_SdcCommondvector.push_front(m_SDCCommand); uqeSection.unlock(); return true; } void CDeliverModule::SendCommand(std::string strcommand, int commandtype) { std::string strlog = ""; if (m_bIsGenErr) { if(!m_CommondType[commandtype].IsClearSendVector) { if (m_pLogFun) { m_pLogFun("In error state,and the command is not nessesery", LOG_V2_WARNING); } return; } } if (m_strcurrentcmd.strCommand!=strcommand) { m_nAKRsubmit=0; m_nCPRsubmit=0; } m_strcurrentcmd.strCommand = strcommand;//保存当前发送的命令 m_strcurrentcmd.nCommmandType=commandtype; ResetEvent(m_hACKEvent); ResetEvent(m_hCPEvent); m_bisNAK=false;//重置NAK状态 m_bisNCP=false; bool isSend=false; //if(m_strcurrentcmd.strCommand.Mid(0,2)!="ST"&&m_strcurrentcmd.strCommand.Mid(0,2)!="HU") //{ // std::string strMessage; // strMessage.Format("%s 是否发送成功!",GetCurrentCommand()); // int result=AfxMessageBox(strMessage,MB_YESNO); // if (result==6) // { // isSend=true; // } // else if (result==7) // { // isSend=false; // } //} //////////////////////// //调用回调函数将指令发送 if(m_pSendData) { //if(isSend) m_pSendData(m_strcurrentcmd.strCommand.c_str(),m_strcurrentcmd.strCommand.length(),m_ClientControl); } else return; /////////////////////////// //int AKTimeOut=0; //if (!isSend) //{ // int result=AfxMessageBox("AK是否超时,选‘是’AK超时,选‘否’CP超时",MB_YESNO); // if (result==6) // { // AKTimeOut=1; // } // else if (result==7) // { // AKTimeOut=-1; // } //} if (m_CommondType[commandtype].IsWaitforACK) { //如果AK超时或者错,则在函数中重发,直接返回,不等CP //if(AKTimeOut==1) { if(!WaitforACK(m_CommondType[commandtype].WaitingTime)) return; } } if (m_CommondType[commandtype].IsWaitforCP) { WaitforCP(m_CommondType[commandtype].WatingCPtime); } } bool CDeliverModule::ReceiveACK (bool IsACK) { if (IsACK) { m_bisNAK=false; if (m_pLogFun) { m_pLogFun("Receive AK!", LOG_V2_INFO); } } else { m_bisNAK=true; if (m_pLogFun) { m_pLogFun("Receive NAK!", LOG_V2_INFO); } } SetEvent(m_hACKEvent); return m_bisNAK; } bool CDeliverModule::WaitforACK(DWORD nWaitingTime) { if (WaitForSingleObject(m_hACKEvent,nWaitingTime) == WAIT_OBJECT_0) { if (m_bisNAK) { if (m_nAKRsubmit