VMSThread.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. /****************************************************************************
  2. * @source : VMSThread.cpp
  3. * @description : VMS Server Socket Thread
  4. ****************************************************************************
  5. * DATE AUTHOR DESCRIPTION
  6. * --------------------------------------------------------------------------
  7. * 2012/03/09 CYM [100] First Cut
  8. *
  9. ****************************************************************************/
  10. //---------------------------------------------------------------------------
  11. #include "../FRAMEWORK/PreHeader.h"
  12. #include "../COMMON/SysGlobal.h"
  13. #include "AppGlobal.h"
  14. #include "VMSThread.h"
  15. //---------------------------------------------------------------------------
  16. #pragma package(smart_init)
  17. //---------------------------------------------------------------------------
  18. // Important: Methods and properties of objects in VCL can only be
  19. // used in a method called using Synchronize, for example:
  20. //
  21. // Synchronize(&UpdateCaption);
  22. //
  23. // where UpdateCaption could look like:
  24. //
  25. // void __fastcall TVMSThread::UpdateCaption()
  26. // {
  27. // Form1->Caption = "Updated in a thread";
  28. // }
  29. //---------------------------------------------------------------------------
  30. /*
  31. * 스레드 생성자
  32. * arguments
  33. * void
  34. * return
  35. * void
  36. */
  37. __fastcall TVMSThread::TVMSThread(TServerSocketThread* ServerSocketThread, TCustomIpClient* ClientSocket, int Tag, bool *ActiveIndicator)
  38. : TClientSocketThread(ServerSocketThread)
  39. {
  40. try
  41. {
  42. m_InitFlag = false;
  43. m_Server.Idx = Tag;
  44. ThreadActiveIndicator = ActiveIndicator;
  45. *ThreadActiveIndicator = true;
  46. // 정보 초기화
  47. ServerInitMem();
  48. ServerInitInfo();
  49. #if 1
  50. pClientSocket = ClientSocket;
  51. pClientSocket->OnError = TcpServerClientError;
  52. #else
  53. pClientSocket = new TCustomIpClient(NULL);
  54. pClientSocket->OnError = TcpServerClientError;
  55. ServerSocketThread->ServerSocket->Accept(pClientSocket);
  56. #endif
  57. Priority = tpNormal;
  58. FreeOnTerminate = true;
  59. Resume();
  60. if ((g_SysInfo->Ini.LogWriteLevel & LOG_DEBUG) || (g_SysInfo->Ini.LogDisplayLevel & LOG_DEBUG))
  61. {
  62. DEBUG_LOG("pClientSocket: 0x%08X", pClientSocket);
  63. }
  64. m_InitFlag = true;
  65. }
  66. catch(...)
  67. {
  68. Terminate();
  69. if ((g_SysInfo->Ini.LogWriteLevel & LOG_DEBUG) || (g_SysInfo->Ini.LogDisplayLevel & LOG_DEBUG))
  70. {
  71. DEBUG_LOG("Thread Init Error");
  72. }
  73. }
  74. }
  75. //---------------------------------------------------------------------------
  76. /*
  77. * 스레드 소멸자
  78. * arguments
  79. * void
  80. * return
  81. * void
  82. */
  83. __fastcall TVMSThread::~TVMSThread()
  84. {
  85. if (pClientSocket != NULL) {
  86. delete pClientSocket;
  87. }
  88. *ThreadActiveIndicator = false;
  89. if ((g_SysInfo->Ini.LogWriteLevel & LOG_INFO) || (g_SysInfo->Ini.LogDisplayLevel & LOG_INFO))
  90. {
  91. INFO_LOG("%s End...", m_strName);
  92. }
  93. _DELETE(m_Log);
  94. }
  95. //---------------------------------------------------------------------------
  96. /*
  97. * 에러 처리 이벤트 핸들러
  98. * arguments
  99. * void
  100. * return
  101. * void
  102. */
  103. void __fastcall TVMSThread::TcpServerClientError(TObject *Sender, int SocketError)
  104. {
  105. if ((g_SysInfo->Ini.LogWriteLevel & LOG_ERROR) || (g_SysInfo->Ini.LogDisplayLevel & LOG_ERROR))
  106. {
  107. LPVOID lpMsgBuf;
  108. FormatMessage(
  109. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  110. NULL,
  111. //GetLastError(),
  112. //MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  113. SocketError,
  114. MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
  115. (LPTSTR) &lpMsgBuf,
  116. 0,
  117. NULL
  118. );
  119. ERROR_LOG("Server Error %d: %s", SocketError, (char *)lpMsgBuf);
  120. LocalFree( lpMsgBuf );
  121. }
  122. pClientSocket->Close();
  123. }
  124. //---------------------------------------------------------------------------
  125. /*
  126. * Tests for socket activity
  127. * arguments
  128. * void
  129. * return
  130. * void
  131. */
  132. bool __fastcall TVMSThread::SocketActivity(void)
  133. {
  134. bool Error, ReadReady, WriteReady, ExcepFlag;
  135. Error = pClientSocket->Select(&ReadReady, &WriteReady, &ExcepFlag, 0);
  136. if ((Error == false) || (ReadReady == true) || (ExcepFlag == true)) {
  137. return true;
  138. } else {
  139. return false;
  140. }
  141. }
  142. //---------------------------------------------------------------------------
  143. /*
  144. * 스레드 실행
  145. * arguments
  146. * void
  147. * return
  148. * void
  149. */
  150. void __fastcall TVMSThread::Execute()
  151. {
  152. BYTE buffer[DEFAULT_TCP_PACKET_MAX_SIZE];
  153. int nRead=0;
  154. int result;
  155. int nError=0;
  156. try
  157. {
  158. while (!Terminated && !m_InitFlag);
  159. NameThreadForDebugging(m_strName);
  160. try
  161. {
  162. while (!Terminated && pClientSocket->Connected)
  163. {
  164. try
  165. {
  166. memset(buffer, 0, sizeof(buffer));
  167. if(pClientSocket->WaitForData(10) || SocketActivity())
  168. {
  169. nRead = pClientSocket->ReceiveBuf(buffer, sizeof(buffer));
  170. if (nRead <= 0)
  171. {
  172. nError = -1;
  173. pClientSocket->Close();
  174. }
  175. else
  176. {
  177. if ((result = RecvPacket(buffer, nRead)) != SYS_ERR_NONE)
  178. {
  179. ProcErrorState(TRUE, result);
  180. }
  181. }
  182. }
  183. ServerStateMachine();
  184. }
  185. catch(...)
  186. {
  187. nError = -2;
  188. pClientSocket->Close();
  189. }
  190. } /* end while */
  191. if ((g_SysInfo->Ini.LogWriteLevel & LOG_DEBUG) || (g_SysInfo->Ini.LogDisplayLevel & LOG_DEBUG))
  192. {
  193. DEBUG_LOG("Terminated:%d Connected:%d Error:%d", Terminated, pClientSocket->Connected, nError);
  194. }
  195. ServerTerminate();
  196. }
  197. __finally
  198. {
  199. pClientSocket->Close();
  200. Terminate();
  201. }
  202. }
  203. catch(...)
  204. {
  205. if ((g_SysInfo->Ini.LogWriteLevel & LOG_DEBUG) || (g_SysInfo->Ini.LogDisplayLevel & LOG_DEBUG))
  206. {
  207. DEBUG_LOG("Thread Execute Error");
  208. }
  209. }
  210. }
  211. //---------------------------------------------------------------------------
  212. /*
  213. * 서버 메모리 할당 루틴
  214. * arguments
  215. * void
  216. * return
  217. * void
  218. */
  219. int __fastcall TVMSThread::ServerInitMem(void)
  220. {
  221. return S_SUCC;
  222. }
  223. //---------------------------------------------------------------------------
  224. /*
  225. * 서버 정보 초기화 루틴
  226. * arguments
  227. * void
  228. * return
  229. * void
  230. */
  231. void __fastcall TVMSThread::ServerInitInfo(void)
  232. {
  233. m_RxLen = 0;
  234. m_TxLen = 0;
  235. m_rTimer = Now();
  236. m_WatchDogTimer = Now();
  237. if (m_Server.Idx >= 0 && m_Server.Idx < G_VMS_COUNT)
  238. {
  239. m_Server.IpAddress = G_VMS_UNIT[m_Server.Idx].IpAddress;
  240. m_Server.Port = VMS_DEFAULT_PORT;
  241. m_Server.Addr = G_VMS_UNIT[m_Server.Idx].LocalNo;
  242. m_Server.VmsId = G_VMS_UNIT[m_Server.Idx].VmsId;
  243. m_pState = &G_VMS_STATE[m_Server.Idx];
  244. } else {
  245. m_Server.IpAddress = "127.0.0.1";
  246. m_Server.Port = VMS_DEFAULT_PORT;
  247. m_Server.Addr = 0;
  248. m_Server.VmsId = "";
  249. m_pState = NULL;
  250. Terminate();
  251. }
  252. m_Server.TimeOut = g_SysInfo->Ini.TimeOut;
  253. m_Server.CycleTime = g_SysInfo->Ini.CycleTime;
  254. m_Server.State = ST_IDLE;
  255. m_Server.sTimer = Now();
  256. m_Server.iRetry = VMS_MAX_RETRY_COUNT;
  257. m_Server.cTimer = Now();
  258. m_strName.sprintf("VMS%03d", m_Server.Addr);
  259. m_Server.LocalCenterId = "";
  260. m_Server.LocalDomainNm = "CENTER";
  261. m_Server.CenterId = "";
  262. m_Server.DomainNm = "VMS";
  263. m_Server.UserName = "";
  264. m_Server.UserPasswd = "";
  265. m_Server.MaxHeartbeatTime = VMS_MAX_HEARTBEAT_TIME;
  266. m_Server.DatagramSize = VMS_MAX_DATAGRAM_SIZE;
  267. m_DataPacketNumber = 0;
  268. m_FrEDConfirmPacketNumber = 0;
  269. m_LoginFlag = false;
  270. m_PublishSerialNbr = 0;
  271. m_Registered.GeneralStatus = false;
  272. m_Registered.ModuleStatus = false;
  273. // 로그 열기
  274. m_Log = new TCOMMLOG(m_strName);
  275. if ((g_SysInfo->Ini.LogWriteLevel & LOG_INFO) || (g_SysInfo->Ini.LogDisplayLevel & LOG_INFO))
  276. {
  277. INFO_LOG("%s Start...", m_strName);
  278. }
  279. }
  280. //---------------------------------------------------------------------------
  281. /*
  282. * 서버 종료
  283. * arguments
  284. * void
  285. * return
  286. * void
  287. */
  288. void __fastcall TVMSThread::ServerTerminate(void)
  289. {
  290. if ((g_SysInfo->Ini.LogWriteLevel & LOG_INFO) || (g_SysInfo->Ini.LogDisplayLevel & LOG_INFO))
  291. {
  292. INFO_LOG("%s Terminate", m_strName);
  293. }
  294. }
  295. //---------------------------------------------------------------------------
  296. /*
  297. * 로그 처리
  298. * arguments
  299. * void
  300. * return
  301. * void
  302. */
  303. void TVMSThread::ProcLog(BYTE bKind, char *fmt, ...)
  304. {
  305. va_list ap;
  306. int cnt;
  307. char szFmtData[LOG_MESSAGE_MAX];
  308. if (m_Log == NULL) return;
  309. try
  310. {
  311. va_start(ap, fmt);
  312. cnt = vsprintf(szFmtData, fmt, ap);
  313. va_end(ap);
  314. if (g_SysInfo->Ini.LogWriteLevel & bKind)
  315. {
  316. m_Log->WriteLog(bKind, szFmtData, cnt);
  317. }
  318. if (g_SysInfo->Ini.LogDisplayLevel & bKind)
  319. {
  320. m_Log->SendLogMessage(bKind, szFmtData, cnt);
  321. }
  322. }
  323. catch (...)
  324. {
  325. }
  326. }
  327. //---------------------------------------------------------------------------
  328. /*
  329. *
  330. * arguments
  331. * void
  332. * return
  333. * void
  334. */
  335. void __fastcall TVMSThread::LOG_WriteTime(Time_t *pTime)
  336. {
  337. if(pTime->time_Year_qty){
  338. DEBUG_LOG("time_Year_qty: %d", *pTime->time_Year_qty);
  339. }
  340. if(pTime->time_Month_qty){
  341. DEBUG_LOG("time_Month_qty: %d", *pTime->time_Month_qty);
  342. }
  343. if(pTime->time_Day_qty){
  344. DEBUG_LOG("time_Day_qty: %d", *pTime->time_Day_qty);
  345. }
  346. DEBUG_LOG("time_Hour_qty: %d", pTime->time_Hour_qty);
  347. DEBUG_LOG("time_Minute_qty: %d", pTime->time_Minute_qty);
  348. DEBUG_LOG("time_Second_qty: %d", pTime->time_Second_qty);
  349. switch(pTime->time_SecondFractions_zz.present){
  350. case time_SecondFractions_PR_deci_seconds:
  351. DEBUG_LOG("deci_seconds: %d", pTime->time_SecondFractions_zz.choice.deci_seconds);
  352. break;
  353. case time_SecondFractions_PR_centi_seconds:
  354. DEBUG_LOG("centi_seconds: %d", pTime->time_SecondFractions_zz.choice.centi_seconds);
  355. break;
  356. case time_SecondFractions_PR_milliseconds:
  357. DEBUG_LOG("milliseconds: %d", pTime->time_SecondFractions_zz.choice.milliseconds);
  358. break;
  359. default:
  360. DEBUG_LOG("Unknown time_SecondFractions %d", pTime->time_SecondFractions_zz.present);
  361. break;
  362. }/* end swtich */
  363. if(pTime->time_Timezone){
  364. DEBUG_LOG("timezone_Hour_qty: %d", pTime->time_Timezone->timezone_Hour_qty);
  365. DEBUG_LOG("time_Minute_qty: %d", pTime->time_Timezone->time_Minute_qty);
  366. }
  367. }
  368. /*--------------------------------------------------------------------------*/
  369. /*
  370. *
  371. * arguments
  372. * void
  373. * return
  374. * void
  375. */
  376. int __fastcall TVMSThread::SaveStateData(void *pData)
  377. {
  378. int result;
  379. result = SYS_ERR_OTHER;
  380. if (m_pState == NULL) return result;
  381. m_pState->Cpsw.Enable = BIT_ENABLE;
  382. m_pState->CollectDate = Now().FormatString("yyyymmddhhnnss");
  383. result = SYS_ERR_NONE;
  384. return result;
  385. }
  386. //---------------------------------------------------------------------------
  387. /*
  388. *
  389. * arguments
  390. * void
  391. * return
  392. * void
  393. */
  394. void __fastcall TVMSThread::ClientResponse(int error)
  395. {
  396. BYTE ErrCode;
  397. int sResult;
  398. int Flag;
  399. bool bSave = false;
  400. switch(error)
  401. {
  402. case SYS_ERR_NONE: break;
  403. case SYS_ERR_OTHER: ErrCode = INT_ERROR_OTHER; break;
  404. case SYS_ERR_INTERNAL: ErrCode = INT_ERROR_SYSTEM; break;
  405. case SYS_ERR_MEMORY: ErrCode = INT_ERROR_SYSTEM; break;
  406. case SYS_ERR_DATABASE: ErrCode = INT_ERROR_SYSTEM; break;
  407. case SYS_ERR_RESET: ErrCode = INT_ERROR_SYSTEM; break;
  408. case SYS_ERR_START: ErrCode = INT_ERROR_SYSTEM; break;
  409. case SYS_ERR_OFFLINE: ErrCode = INT_ERROR_OFFLINE; break;
  410. case SYS_ERR_NO_RES: ErrCode = INT_ERROR_NO_RESPONSE; break;
  411. case SYS_ERR_ACCESS: ErrCode = INT_ERROR_PROCESS; break;
  412. case SYS_ERR_INVALID: ErrCode = INT_ERROR_OTHER; break;
  413. case SYS_ERR_UNKNOWN: ErrCode = INT_ERROR_UNKNOWN_CODE; break;
  414. case SYS_ERR_WRITE_LENGTH: ErrCode = INT_ERROR_OTHER; break;
  415. case SYS_ERR_PACKET_SIZE_LARGE: ErrCode = INT_ERROR_OTHER; break;
  416. case SYS_ERR_INVALID_TAG: ErrCode = INT_ERROR_OTHER; break;
  417. case SYS_ERR_CRC: ErrCode = INT_ERROR_OTHER; break;
  418. case SYS_ERR_LENGTH: ErrCode = INT_ERROR_LENGTH; break;
  419. case SYS_ERR_ADDRESS: ErrCode = INT_ERROR_ADDRESS; break;
  420. case SYS_ERR_HEADER_OPTIONS: ErrCode = INT_ERROR_HEADER; break;
  421. case SYS_ERR_UNKNOWN_COMMAND: ErrCode = INT_ERROR_UNKNOWN_OPCODE; break;
  422. case SYS_ERR_RECEIVE_TIMEOUT: ErrCode = INT_ERROR_OTHER; break;
  423. case SYS_ERR_DATA_SIZE: ErrCode = INT_ERROR_DISCORD; break;
  424. case SYS_ERR_MISMATCH: ErrCode = INT_ERROR_OTHER; break;
  425. case SYS_ERR_INVALID_PARA: ErrCode = INT_ERROR_INVALID_DATA; break;
  426. case SYS_ERR_MOVEMENT: ErrCode = INT_ERROR_MOVEMENT; break;
  427. case SYS_ERR_UNAUTHORIZED: ErrCode = INT_ERROR_UNAUTHORIZED; break;
  428. default: ErrCode = INT_ERROR_OTHER; break;
  429. }/* end switch */
  430. switch (m_Req.OpCode)
  431. {
  432. case INT_OP_VMS_POWER_CTL: /* 0x0303 VMS 통신 서버, VMS 전광판 On/Off 제어 */
  433. if (error == SYS_ERR_NONE){
  434. Flag = SEND_ACK;
  435. m_Set.Data.Control.Result = CTL_RESULT_SUCC;
  436. } else {
  437. Flag = SEND_NACK;
  438. }/* end if */
  439. bSave = true;
  440. break;
  441. case INT_OP_VMS_PARA_SET: /* 0x0308 VMS 통신 서버, VMS 환경설정정보 전송 */
  442. if (error == SYS_ERR_NONE){
  443. Flag = SEND_ACK;
  444. bSave = true;
  445. } else {
  446. Flag = SEND_NACK;
  447. }/* end if */
  448. break;
  449. case INT_OP_VMS_RESET: /* 0x0309 VMS 통신 서버, VMS 제어기 리셋 전송 */
  450. if (error == SYS_ERR_NONE){
  451. Flag = SEND_ACK;
  452. m_Set.Data.Control.Result = CTL_RESULT_SUCC;
  453. } else {
  454. Flag = SEND_NACK;
  455. }/* end if */
  456. bSave = true;
  457. break;
  458. default:
  459. Flag = SEND_NONE;
  460. break;
  461. }/* end switch */
  462. if (bSave == true) {
  463. if ((sResult = SendCommDataMessage(WM_DATA_SAVE, (void *)&m_Set, sizeof(m_Set))) != SYS_ERR_NONE)
  464. {
  465. if ((g_SysInfo->Ini.LogWriteLevel & LOG_ERROR) || (g_SysInfo->Ini.LogDisplayLevel & LOG_ERROR))
  466. {
  467. ERROR_LOG("SendCommDataMessage Error %d", sResult);
  468. }
  469. }
  470. }/* end if */
  471. if (Flag == SEND_ACK){
  472. INT_ACK_RES Ack;
  473. memset(&Ack, 0x00, sizeof(Ack));
  474. Ack.OPCode.Type = INT_TYPE(m_Req.OpCode);
  475. Ack.OPCode.Kind = INT_KIND(m_Req.OpCode);
  476. Ack.MsgSeq = m_Req.MsgSeq;
  477. if ((sResult = AckRes(&Ack, m_Req.ProcessID)) != UDP_ERR_NONE){
  478. if ((g_SysInfo->Ini.LogWriteLevel & LOG_DEBUG) || (g_SysInfo->Ini.LogDisplayLevel & LOG_DEBUG))
  479. {
  480. DEBUG_LOG("AckRes fail %d", sResult);
  481. }
  482. }
  483. } else if (Flag == SEND_NACK){
  484. INT_NACK_RES Nack;
  485. memset(&Nack, 0x00, sizeof(Nack));
  486. Nack.OPCode.Type = INT_TYPE(m_Req.OpCode);
  487. Nack.OPCode.Kind = INT_KIND(m_Req.OpCode);
  488. Nack.MsgSeq = m_Req.MsgSeq;
  489. Nack.ErrCode = ErrCode;
  490. if ((sResult = NackRes(&Nack, m_Req.ProcessID)) != UDP_ERR_NONE){
  491. if ((g_SysInfo->Ini.LogWriteLevel & LOG_DEBUG) || (g_SysInfo->Ini.LogDisplayLevel & LOG_DEBUG))
  492. {
  493. DEBUG_LOG("NackRes fail %d", sResult);
  494. }
  495. }
  496. }/* end if */
  497. }
  498. //---------------------------------------------------------------------------
  499. /*
  500. *
  501. * arguments
  502. * void
  503. * return
  504. * void
  505. */
  506. int __fastcall TVMSThread::SendCommMessage(UINT Msg, int wParam, int lParam)
  507. {
  508. int result;
  509. result = SYS_ERR_OTHER;
  510. if (g_SysInfo->State.CommThreadID != NULL){
  511. if (PostThreadMessage(g_SysInfo->State.CommThreadID, Msg, (WPARAM)wParam, (LPARAM)lParam)){
  512. result = SYS_ERR_NONE;
  513. }else{
  514. result = SYS_ERR_INTERNAL;
  515. }
  516. }
  517. return result;
  518. }
  519. //---------------------------------------------------------------------------
  520. /*
  521. *
  522. * arguments
  523. * void
  524. * return
  525. * void
  526. */
  527. int __fastcall TVMSThread::SendCommDataMessage(UINT Msg, void *pData, int iLen)
  528. {
  529. int result;
  530. char *p;
  531. result = SYS_ERR_OTHER;
  532. if (g_SysInfo->State.CommThreadID != NULL){
  533. p = new char[iLen];
  534. if (p != NULL){
  535. try
  536. {
  537. memcpy(p, pData, iLen);
  538. if (PostThreadMessage(g_SysInfo->State.CommThreadID, Msg, (WPARAM)p, NULL)){
  539. result = SYS_ERR_NONE;
  540. Sleep(50);
  541. }else{
  542. result = SYS_ERR_INTERNAL;
  543. }
  544. }
  545. __finally
  546. {
  547. if (result != SYS_ERR_NONE) delete []p;
  548. }
  549. }else{
  550. result = SYS_ERR_MEMORY;
  551. }
  552. }
  553. return result;
  554. }
  555. //---------------------------------------------------------------------------