/**************************************************************************** * @source : VMSThread.cpp * @description : VMS Server Socket Thread **************************************************************************** * DATE AUTHOR DESCRIPTION * -------------------------------------------------------------------------- * 2012/03/09 CYM [100] First Cut * ****************************************************************************/ //--------------------------------------------------------------------------- #include "../FRAMEWORK/PreHeader.h" #include "../COMMON/SysGlobal.h" #include "AppGlobal.h" #include "VMSThread.h" //--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- // Important: Methods and properties of objects in VCL can only be // used in a method called using Synchronize, for example: // // Synchronize(&UpdateCaption); // // where UpdateCaption could look like: // // void __fastcall TVMSThread::UpdateCaption() // { // Form1->Caption = "Updated in a thread"; // } //--------------------------------------------------------------------------- /* * ½º·¹µå »ý¼ºÀÚ * arguments * void * return * void */ __fastcall TVMSThread::TVMSThread(TServerSocketThread* ServerSocketThread, TCustomIpClient* ClientSocket, int Tag, bool *ActiveIndicator) : TClientSocketThread(ServerSocketThread) { try { m_InitFlag = false; m_Server.Idx = Tag; ThreadActiveIndicator = ActiveIndicator; *ThreadActiveIndicator = true; // Á¤º¸ ÃʱâÈ­ ServerInitMem(); ServerInitInfo(); #if 1 pClientSocket = ClientSocket; pClientSocket->OnError = TcpServerClientError; #else pClientSocket = new TCustomIpClient(NULL); pClientSocket->OnError = TcpServerClientError; ServerSocketThread->ServerSocket->Accept(pClientSocket); #endif Priority = tpNormal; FreeOnTerminate = true; Resume(); if ((g_SysInfo->Ini.LogWriteLevel & LOG_DEBUG) || (g_SysInfo->Ini.LogDisplayLevel & LOG_DEBUG)) { DEBUG_LOG("pClientSocket: 0x%08X", pClientSocket); } m_InitFlag = true; } catch(...) { Terminate(); if ((g_SysInfo->Ini.LogWriteLevel & LOG_DEBUG) || (g_SysInfo->Ini.LogDisplayLevel & LOG_DEBUG)) { DEBUG_LOG("Thread Init Error"); } } } //--------------------------------------------------------------------------- /* * ½º·¹µå ¼Ò¸êÀÚ * arguments * void * return * void */ __fastcall TVMSThread::~TVMSThread() { if (pClientSocket != NULL) { delete pClientSocket; } *ThreadActiveIndicator = false; if ((g_SysInfo->Ini.LogWriteLevel & LOG_INFO) || (g_SysInfo->Ini.LogDisplayLevel & LOG_INFO)) { INFO_LOG("%s End...", m_strName); } _DELETE(m_Log); } //--------------------------------------------------------------------------- /* * ¿¡·¯ ó¸® À̺¥Æ® Çڵ鷯 * arguments * void * return * void */ void __fastcall TVMSThread::TcpServerClientError(TObject *Sender, int SocketError) { if ((g_SysInfo->Ini.LogWriteLevel & LOG_ERROR) || (g_SysInfo->Ini.LogDisplayLevel & LOG_ERROR)) { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, //GetLastError(), //MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language SocketError, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); ERROR_LOG("Server Error %d: %s", SocketError, (char *)lpMsgBuf); LocalFree( lpMsgBuf ); } pClientSocket->Close(); } //--------------------------------------------------------------------------- /* * Tests for socket activity * arguments * void * return * void */ bool __fastcall TVMSThread::SocketActivity(void) { bool Error, ReadReady, WriteReady, ExcepFlag; Error = pClientSocket->Select(&ReadReady, &WriteReady, &ExcepFlag, 0); if ((Error == false) || (ReadReady == true) || (ExcepFlag == true)) { return true; } else { return false; } } //--------------------------------------------------------------------------- /* * ½º·¹µå ½ÇÇà * arguments * void * return * void */ void __fastcall TVMSThread::Execute() { BYTE buffer[DEFAULT_TCP_PACKET_MAX_SIZE]; int nRead=0; int result; int nError=0; try { while (!Terminated && !m_InitFlag); NameThreadForDebugging(m_strName); try { while (!Terminated && pClientSocket->Connected) { try { memset(buffer, 0, sizeof(buffer)); if(pClientSocket->WaitForData(10) || SocketActivity()) { nRead = pClientSocket->ReceiveBuf(buffer, sizeof(buffer)); if (nRead <= 0) { nError = -1; pClientSocket->Close(); } else { if ((result = RecvPacket(buffer, nRead)) != SYS_ERR_NONE) { ProcErrorState(TRUE, result); } } } ServerStateMachine(); } catch(...) { nError = -2; pClientSocket->Close(); } } /* end while */ if ((g_SysInfo->Ini.LogWriteLevel & LOG_DEBUG) || (g_SysInfo->Ini.LogDisplayLevel & LOG_DEBUG)) { DEBUG_LOG("Terminated:%d Connected:%d Error:%d", Terminated, pClientSocket->Connected, nError); } ServerTerminate(); } __finally { pClientSocket->Close(); Terminate(); } } catch(...) { if ((g_SysInfo->Ini.LogWriteLevel & LOG_DEBUG) || (g_SysInfo->Ini.LogDisplayLevel & LOG_DEBUG)) { DEBUG_LOG("Thread Execute Error"); } } } //--------------------------------------------------------------------------- /* * ¼­¹ö ¸Þ¸ð¸® ÇÒ´ç ·çÆ¾ * arguments * void * return * void */ int __fastcall TVMSThread::ServerInitMem(void) { return S_SUCC; } //--------------------------------------------------------------------------- /* * ¼­¹ö Á¤º¸ ÃʱâÈ­ ·çƾ * arguments * void * return * void */ void __fastcall TVMSThread::ServerInitInfo(void) { m_RxLen = 0; m_TxLen = 0; m_rTimer = Now(); m_WatchDogTimer = Now(); if (m_Server.Idx >= 0 && m_Server.Idx < G_VMS_COUNT) { m_Server.IpAddress = G_VMS_UNIT[m_Server.Idx].IpAddress; m_Server.Port = VMS_DEFAULT_PORT; m_Server.Addr = G_VMS_UNIT[m_Server.Idx].LocalNo; m_Server.VmsId = G_VMS_UNIT[m_Server.Idx].VmsId; m_pState = &G_VMS_STATE[m_Server.Idx]; } else { m_Server.IpAddress = "127.0.0.1"; m_Server.Port = VMS_DEFAULT_PORT; m_Server.Addr = 0; m_Server.VmsId = ""; m_pState = NULL; Terminate(); } m_Server.TimeOut = g_SysInfo->Ini.TimeOut; m_Server.CycleTime = g_SysInfo->Ini.CycleTime; m_Server.State = ST_IDLE; m_Server.sTimer = Now(); m_Server.iRetry = VMS_MAX_RETRY_COUNT; m_Server.cTimer = Now(); m_strName.sprintf("VMS%03d", m_Server.Addr); m_Server.LocalCenterId = ""; m_Server.LocalDomainNm = "CENTER"; m_Server.CenterId = ""; m_Server.DomainNm = "VMS"; m_Server.UserName = ""; m_Server.UserPasswd = ""; m_Server.MaxHeartbeatTime = VMS_MAX_HEARTBEAT_TIME; m_Server.DatagramSize = VMS_MAX_DATAGRAM_SIZE; m_DataPacketNumber = 0; m_FrEDConfirmPacketNumber = 0; m_LoginFlag = false; m_PublishSerialNbr = 0; m_Registered.GeneralStatus = false; m_Registered.ModuleStatus = false; // ·Î±× ¿­±â m_Log = new TCOMMLOG(m_strName); if ((g_SysInfo->Ini.LogWriteLevel & LOG_INFO) || (g_SysInfo->Ini.LogDisplayLevel & LOG_INFO)) { INFO_LOG("%s Start...", m_strName); } } //--------------------------------------------------------------------------- /* * ¼­¹ö Á¾·á * arguments * void * return * void */ void __fastcall TVMSThread::ServerTerminate(void) { if ((g_SysInfo->Ini.LogWriteLevel & LOG_INFO) || (g_SysInfo->Ini.LogDisplayLevel & LOG_INFO)) { INFO_LOG("%s Terminate", m_strName); } } //--------------------------------------------------------------------------- /* * ·Î±× ó¸® * arguments * void * return * void */ void TVMSThread::ProcLog(BYTE bKind, char *fmt, ...) { va_list ap; int cnt; char szFmtData[LOG_MESSAGE_MAX]; if (m_Log == NULL) return; try { va_start(ap, fmt); cnt = vsprintf(szFmtData, fmt, ap); va_end(ap); if (g_SysInfo->Ini.LogWriteLevel & bKind) { m_Log->WriteLog(bKind, szFmtData, cnt); } if (g_SysInfo->Ini.LogDisplayLevel & bKind) { m_Log->SendLogMessage(bKind, szFmtData, cnt); } } catch (...) { } } //--------------------------------------------------------------------------- /* * * arguments * void * return * void */ void __fastcall TVMSThread::LOG_WriteTime(Time_t *pTime) { if(pTime->time_Year_qty){ DEBUG_LOG("time_Year_qty: %d", *pTime->time_Year_qty); } if(pTime->time_Month_qty){ DEBUG_LOG("time_Month_qty: %d", *pTime->time_Month_qty); } if(pTime->time_Day_qty){ DEBUG_LOG("time_Day_qty: %d", *pTime->time_Day_qty); } DEBUG_LOG("time_Hour_qty: %d", pTime->time_Hour_qty); DEBUG_LOG("time_Minute_qty: %d", pTime->time_Minute_qty); DEBUG_LOG("time_Second_qty: %d", pTime->time_Second_qty); switch(pTime->time_SecondFractions_zz.present){ case time_SecondFractions_PR_deci_seconds: DEBUG_LOG("deci_seconds: %d", pTime->time_SecondFractions_zz.choice.deci_seconds); break; case time_SecondFractions_PR_centi_seconds: DEBUG_LOG("centi_seconds: %d", pTime->time_SecondFractions_zz.choice.centi_seconds); break; case time_SecondFractions_PR_milliseconds: DEBUG_LOG("milliseconds: %d", pTime->time_SecondFractions_zz.choice.milliseconds); break; default: DEBUG_LOG("Unknown time_SecondFractions %d", pTime->time_SecondFractions_zz.present); break; }/* end swtich */ if(pTime->time_Timezone){ DEBUG_LOG("timezone_Hour_qty: %d", pTime->time_Timezone->timezone_Hour_qty); DEBUG_LOG("time_Minute_qty: %d", pTime->time_Timezone->time_Minute_qty); } } /*--------------------------------------------------------------------------*/ /* * * arguments * void * return * void */ int __fastcall TVMSThread::SaveStateData(void *pData) { int result; result = SYS_ERR_OTHER; if (m_pState == NULL) return result; m_pState->Cpsw.Enable = BIT_ENABLE; m_pState->CollectDate = Now().FormatString("yyyymmddhhnnss"); result = SYS_ERR_NONE; return result; } //--------------------------------------------------------------------------- /* * * arguments * void * return * void */ void __fastcall TVMSThread::ClientResponse(int error) { BYTE ErrCode; int sResult; int Flag; bool bSave = false; switch(error) { case SYS_ERR_NONE: break; case SYS_ERR_OTHER: ErrCode = INT_ERROR_OTHER; break; case SYS_ERR_INTERNAL: ErrCode = INT_ERROR_SYSTEM; break; case SYS_ERR_MEMORY: ErrCode = INT_ERROR_SYSTEM; break; case SYS_ERR_DATABASE: ErrCode = INT_ERROR_SYSTEM; break; case SYS_ERR_RESET: ErrCode = INT_ERROR_SYSTEM; break; case SYS_ERR_START: ErrCode = INT_ERROR_SYSTEM; break; case SYS_ERR_OFFLINE: ErrCode = INT_ERROR_OFFLINE; break; case SYS_ERR_NO_RES: ErrCode = INT_ERROR_NO_RESPONSE; break; case SYS_ERR_ACCESS: ErrCode = INT_ERROR_PROCESS; break; case SYS_ERR_INVALID: ErrCode = INT_ERROR_OTHER; break; case SYS_ERR_UNKNOWN: ErrCode = INT_ERROR_UNKNOWN_CODE; break; case SYS_ERR_WRITE_LENGTH: ErrCode = INT_ERROR_OTHER; break; case SYS_ERR_PACKET_SIZE_LARGE: ErrCode = INT_ERROR_OTHER; break; case SYS_ERR_INVALID_TAG: ErrCode = INT_ERROR_OTHER; break; case SYS_ERR_CRC: ErrCode = INT_ERROR_OTHER; break; case SYS_ERR_LENGTH: ErrCode = INT_ERROR_LENGTH; break; case SYS_ERR_ADDRESS: ErrCode = INT_ERROR_ADDRESS; break; case SYS_ERR_HEADER_OPTIONS: ErrCode = INT_ERROR_HEADER; break; case SYS_ERR_UNKNOWN_COMMAND: ErrCode = INT_ERROR_UNKNOWN_OPCODE; break; case SYS_ERR_RECEIVE_TIMEOUT: ErrCode = INT_ERROR_OTHER; break; case SYS_ERR_DATA_SIZE: ErrCode = INT_ERROR_DISCORD; break; case SYS_ERR_MISMATCH: ErrCode = INT_ERROR_OTHER; break; case SYS_ERR_INVALID_PARA: ErrCode = INT_ERROR_INVALID_DATA; break; case SYS_ERR_MOVEMENT: ErrCode = INT_ERROR_MOVEMENT; break; case SYS_ERR_UNAUTHORIZED: ErrCode = INT_ERROR_UNAUTHORIZED; break; default: ErrCode = INT_ERROR_OTHER; break; }/* end switch */ switch (m_Req.OpCode) { case INT_OP_VMS_POWER_CTL: /* 0x0303 VMS Åë½Å ¼­¹ö, VMS Àü±¤ÆÇ On/Off Á¦¾î */ if (error == SYS_ERR_NONE){ Flag = SEND_ACK; m_Set.Data.Control.Result = CTL_RESULT_SUCC; } else { Flag = SEND_NACK; }/* end if */ bSave = true; break; case INT_OP_VMS_PARA_SET: /* 0x0308 VMS Åë½Å ¼­¹ö, VMS ȯ°æ¼³Á¤Á¤º¸ Àü¼Û */ if (error == SYS_ERR_NONE){ Flag = SEND_ACK; bSave = true; } else { Flag = SEND_NACK; }/* end if */ break; case INT_OP_VMS_RESET: /* 0x0309 VMS Åë½Å ¼­¹ö, VMS Á¦¾î±â ¸®¼Â Àü¼Û */ if (error == SYS_ERR_NONE){ Flag = SEND_ACK; m_Set.Data.Control.Result = CTL_RESULT_SUCC; } else { Flag = SEND_NACK; }/* end if */ bSave = true; break; default: Flag = SEND_NONE; break; }/* end switch */ if (bSave == true) { if ((sResult = SendCommDataMessage(WM_DATA_SAVE, (void *)&m_Set, sizeof(m_Set))) != SYS_ERR_NONE) { if ((g_SysInfo->Ini.LogWriteLevel & LOG_ERROR) || (g_SysInfo->Ini.LogDisplayLevel & LOG_ERROR)) { ERROR_LOG("SendCommDataMessage Error %d", sResult); } } }/* end if */ if (Flag == SEND_ACK){ INT_ACK_RES Ack; memset(&Ack, 0x00, sizeof(Ack)); Ack.OPCode.Type = INT_TYPE(m_Req.OpCode); Ack.OPCode.Kind = INT_KIND(m_Req.OpCode); Ack.MsgSeq = m_Req.MsgSeq; if ((sResult = AckRes(&Ack, m_Req.ProcessID)) != UDP_ERR_NONE){ if ((g_SysInfo->Ini.LogWriteLevel & LOG_DEBUG) || (g_SysInfo->Ini.LogDisplayLevel & LOG_DEBUG)) { DEBUG_LOG("AckRes fail %d", sResult); } } } else if (Flag == SEND_NACK){ INT_NACK_RES Nack; memset(&Nack, 0x00, sizeof(Nack)); Nack.OPCode.Type = INT_TYPE(m_Req.OpCode); Nack.OPCode.Kind = INT_KIND(m_Req.OpCode); Nack.MsgSeq = m_Req.MsgSeq; Nack.ErrCode = ErrCode; if ((sResult = NackRes(&Nack, m_Req.ProcessID)) != UDP_ERR_NONE){ if ((g_SysInfo->Ini.LogWriteLevel & LOG_DEBUG) || (g_SysInfo->Ini.LogDisplayLevel & LOG_DEBUG)) { DEBUG_LOG("NackRes fail %d", sResult); } } }/* end if */ } //--------------------------------------------------------------------------- /* * * arguments * void * return * void */ int __fastcall TVMSThread::SendCommMessage(UINT Msg, int wParam, int lParam) { int result; result = SYS_ERR_OTHER; if (g_SysInfo->State.CommThreadID != NULL){ if (PostThreadMessage(g_SysInfo->State.CommThreadID, Msg, (WPARAM)wParam, (LPARAM)lParam)){ result = SYS_ERR_NONE; }else{ result = SYS_ERR_INTERNAL; } } return result; } //--------------------------------------------------------------------------- /* * * arguments * void * return * void */ int __fastcall TVMSThread::SendCommDataMessage(UINT Msg, void *pData, int iLen) { int result; char *p; result = SYS_ERR_OTHER; if (g_SysInfo->State.CommThreadID != NULL){ p = new char[iLen]; if (p != NULL){ try { memcpy(p, pData, iLen); if (PostThreadMessage(g_SysInfo->State.CommThreadID, Msg, (WPARAM)p, NULL)){ result = SYS_ERR_NONE; Sleep(50); }else{ result = SYS_ERR_INTERNAL; } } __finally { if (result != SYS_ERR_NONE) delete []p; } }else{ result = SYS_ERR_MEMORY; } } return result; } //---------------------------------------------------------------------------