123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651 |
- /****************************************************************************
- * @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;
- }
- //---------------------------------------------------------------------------
|