VMSCThread.cpp 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686
  1. //---------------------------------------------------------------------------
  2. #include "AppGlobalF.h"
  3. #include "VMSCThread.h"
  4. #include "FrmSysLogF.h"
  5. #include "FrmVmsInfoF.h"
  6. #include "FrmVmsLogF.h"
  7. #include <winsock.h>
  8. //---------------------------------------------------------------------------
  9. #pragma package(smart_init)
  10. //---------------------------------------------------------------------------
  11. // Important: Methods and properties of objects in VCL can only be
  12. // used in a method called using Synchronize, for example:
  13. //
  14. // Synchronize(&UpdateCaption);
  15. //
  16. // where UpdateCaption could look like:
  17. //
  18. // void __fastcall TVMSCThread::UpdateCaption()
  19. // {
  20. // Form1->Caption = "Updated in a thread";
  21. // }
  22. //---------------------------------------------------------------------------
  23. #define VMSID FVmsObj->VmsId
  24. /*
  25. * 스레드 생성자
  26. * arguments
  27. * void
  28. * return
  29. * void
  30. */
  31. __fastcall TVMSCThread::TVMSCThread(bool CreateSuspended, int Tag, bool *ActiveIndicator)
  32. : TThread(CreateSuspended)
  33. {
  34. try
  35. {
  36. FUserTerm = false;
  37. FVmsObj = (TVmsCtlr*)Tag;
  38. FLogFile = FVmsObj->FCLog;
  39. ThreadActiveIndicator = ActiveIndicator;
  40. *ThreadActiveIndicator = true;
  41. // 정보 초기화
  42. ClientInitInfo();
  43. TcpClient = new TTcpClient(NULL);
  44. TcpClient->RemoteHost = FVmsObj->IpAddress;
  45. TcpClient->RemotePort = FVmsObj->LocalNo;
  46. TcpClient->BlockMode = bmBlocking;
  47. TcpClient->OnConnect = TcpClientConnect;
  48. TcpClient->OnCreateHandle = TcpClientCreateHandle;
  49. TcpClient->OnDestroyHandle = TcpClientDestroyHandle;
  50. TcpClient->OnDisconnect = TcpClientDisconnect;
  51. TcpClient->OnError = TcpClientError;
  52. TcpClient->OnReceive = TcpClientReceive;
  53. TcpClient->OnSend = TcpClientSend;
  54. Priority = tpNormal;
  55. FreeOnTerminate = true;
  56. Resume();
  57. }
  58. catch(Exception &e)
  59. {
  60. SERROR("Thread Init Error");
  61. Terminate();
  62. }
  63. }
  64. //---------------------------------------------------------------------------
  65. /*
  66. * 스레드 소멸자
  67. * arguments
  68. * void
  69. * return
  70. * void
  71. */
  72. __fastcall TVMSCThread::~TVMSCThread()
  73. {
  74. try
  75. {
  76. FVmsObj->Client.Status = process_fail;
  77. SAFE_DELETE(TcpClient);
  78. }
  79. catch(Exception &e)
  80. {
  81. }
  82. *ThreadActiveIndicator = false;
  83. }
  84. //---------------------------------------------------------------------------
  85. /*
  86. * 연결 이벤트 핸들러
  87. * arguments
  88. * void
  89. * return
  90. * void
  91. */
  92. void __fastcall TVMSCThread::TcpClientConnect(TObject *Sender)
  93. {
  94. SINFO("Server Connect ok: %s %s", TcpClient->RemoteHost.c_str(), TcpClient->RemotePort.c_str());
  95. ClientInitInfo();
  96. FVmsObj->Client.Comm = state_open;
  97. FVmsObj->Client.Status = process_run;
  98. FVmsObj->ConnectTm = Now().DateTimeString();
  99. FVmsObj->Server.Status = process_run;
  100. POST_MSG(MAINHANDLE, WM_VMS_THREAD, WM_VMS_SERVER_STTS, (int)FVmsObj);
  101. POST_MSG(MAINHANDLE, WM_VMS_THREAD, WM_VMS_CLIENT_STTS, (int)FVmsObj);
  102. }
  103. //---------------------------------------------------------------------------
  104. /*
  105. * 연결 해제 이벤트 핸들러
  106. * arguments
  107. * void
  108. * return
  109. * void
  110. */
  111. void __fastcall TVMSCThread::TcpClientDisconnect(TObject *Sender)
  112. {
  113. FVmsObj->Client.Comm = state_close;
  114. FVmsObj->Client.Status = process_run;
  115. m_pState->Comm = vms_error;
  116. FVmsObj->DisconnectTm = Now().DateTimeString();
  117. FVmsObj->Server.Status == process_fail;
  118. //POST_MSG(MAINHANDLE, WM_VMS_THREAD, WM_VMS_CLIENT_STTS, (int)FVmsObj);
  119. SINFO("Server Disconnect: %s %s", TcpClient->RemoteHost.c_str(), TcpClient->RemotePort.c_str());
  120. POST_MSG(MAINHANDLE, WM_VMS_THREAD, WM_VMS_SERVER_STTS, (int)FVmsObj);
  121. }
  122. //---------------------------------------------------------------------------
  123. /*
  124. * 핸들 생성 이벤트 핸들러
  125. * arguments
  126. * void
  127. * return
  128. * void
  129. */
  130. void __fastcall TVMSCThread::TcpClientCreateHandle(TObject *Sender)
  131. {
  132. //LDEBUG("Thread Create Handle");
  133. }
  134. //---------------------------------------------------------------------------
  135. /*
  136. * 핸들 소멸 이벤트 핸들러
  137. * arguments
  138. * void
  139. * return
  140. * void
  141. */
  142. void __fastcall TVMSCThread::TcpClientDestroyHandle(TObject *Sender)
  143. {
  144. //LDEBUG("Thread Destroy Handle");
  145. }
  146. //---------------------------------------------------------------------------
  147. void __fastcall TVMSCThread::Close(void)
  148. {
  149. try
  150. {
  151. FVmsObj->Client.Status == process_fail;
  152. if (TcpClient)
  153. {
  154. //if (TcpClient->Connected)
  155. {
  156. TcpClient->Close();
  157. //Sleep(3000);
  158. }
  159. }
  160. }
  161. catch(Exception &e)
  162. {
  163. }
  164. }
  165. //---------------------------------------------------------------------------
  166. /*
  167. * 에러 처리 이벤트 핸들러
  168. * arguments
  169. * void
  170. * return
  171. * void
  172. */
  173. void __fastcall TVMSCThread::TcpClientError(TObject *Sender, int SocketError)
  174. {
  175. LPVOID lpMsgBuf = NULL;
  176. try
  177. {
  178. try
  179. {
  180. FormatMessage(
  181. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  182. NULL,
  183. //GetLastError(),
  184. //MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  185. SocketError,
  186. MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
  187. (LPTSTR) &lpMsgBuf,
  188. 0,
  189. NULL
  190. );
  191. char *pData = (char*)lpMsgBuf;
  192. if (strlen(pData) > 2)
  193. {
  194. pData[strlen(pData)-2] = 0x00;
  195. pData[strlen(pData)-1] = 0x00;
  196. }
  197. SERROR("SocketError: (%d: %s)", SocketError, pData);
  198. }
  199. __finally
  200. {
  201. if (lpMsgBuf) LocalFree(lpMsgBuf);
  202. lpMsgBuf = NULL;
  203. }
  204. }
  205. catch(Exception &e)
  206. {
  207. }
  208. Close();
  209. }
  210. //---------------------------------------------------------------------------
  211. /*
  212. * 데이터 수신 이벤트 핸들러
  213. * arguments
  214. * void
  215. * return
  216. * void
  217. */
  218. void __fastcall TVMSCThread::TcpClientReceive(TObject *Sender, char *Buf, int &DataLen)
  219. {
  220. //LDEBUG("VMS Client Receive: %s, %d", VMSID.c_str(), DataLen);
  221. }
  222. //---------------------------------------------------------------------------
  223. /*
  224. * 데이터 송신 이벤트 핸들러
  225. * arguments
  226. * void
  227. * return
  228. * void
  229. */
  230. void __fastcall TVMSCThread::TcpClientSend(TObject *Sender, char *Buf, int &DataLen)
  231. {
  232. //LDEBUG("VMS Client Send: %s, %d", VMSID.c_str(), DataLen);
  233. }
  234. //---------------------------------------------------------------------------
  235. bool __fastcall TVMSCThread::SocketActivity(bool &AError)
  236. {
  237. bool Error, ReadReady, WriteReady, ExcepFlag;
  238. ReadReady = false;
  239. AError = false;
  240. if (!TcpClient) return ReadReady;
  241. try
  242. {
  243. Error = TcpClient->Select(&ReadReady, &WriteReady, &ExcepFlag, 0);
  244. if ((Error == false))// || (ExcepFlag == true)) //exception flag == o.o.b(out of band data receive)
  245. {
  246. AError = true;
  247. ReadReady = false;
  248. }
  249. }
  250. catch(Exception &e)
  251. {
  252. AError = true;
  253. ReadReady = false;
  254. }
  255. return ReadReady;
  256. }
  257. //---------------------------------------------------------------------------
  258. bool __fastcall TVMSCThread::SocketActivity()
  259. {
  260. bool bResult = false;
  261. bool Error, ReadReady, WriteReady, ExcepFlag;
  262. if (!TcpClient) return bResult;
  263. try
  264. {
  265. Error = TcpClient->Select(&ReadReady, &WriteReady, &ExcepFlag, 0);
  266. if ((Error == false) || (ReadReady == true) || (ExcepFlag == true))
  267. {
  268. bResult = true;
  269. }
  270. }
  271. catch(Exception &e)
  272. {
  273. }
  274. return bResult;
  275. }
  276. //---------------------------------------------------------------------------
  277. /*
  278. * 클라이언트 정보 초기화 루틴
  279. * arguments
  280. * void
  281. * return
  282. * void
  283. */
  284. void __fastcall TVMSCThread::ClientInitInfo(void)
  285. {
  286. m_RxLen = 0;
  287. m_rcvPacketTimer = Now();
  288. m_WatchDogTimer = Now();
  289. m_pVmsFormList = FVmsObj->pForms;
  290. m_pState = &FVmsObj->RSTATE;
  291. FClient.State = CT_IDLE;
  292. FClient.IpAddress = FVmsObj->IpAddress;
  293. FClient.Port = FVmsObj->LocalNo;
  294. FClient.Addr = FVmsObj->Id;
  295. FClient.VmsId = FVmsObj->VmsId;
  296. FClient.TimeOut = g_AppCfg.comm.nCmdTimeOut;
  297. FClient.pollingCycleTime = g_AppCfg.comm.nPollingTime;
  298. FClient.reqStatusTimer = Now() - ITSCOMM_SECTIME(FClient.pollingCycleTime+10);
  299. FClient.sendRetry = VMS_MAX_RETRY_COUNT;
  300. FClient.sendTimer = Now();
  301. //m_strName.sprintf("VMSC%03d", FClient.Addr);
  302. m_strName = "VMSC" + FVmsObj->VmsId;
  303. FClient.LocalCenterId = "";
  304. FClient.CenterId = "";
  305. FClient.LocalDomainNm = g_AppCfg.comm.sLocalDomain;
  306. FClient.DomainNm = FClient.VmsId;
  307. FClient.UserName = g_AppCfg.comm.sLoginUser;
  308. FClient.UserPasswd = g_AppCfg.comm.sLoginPswd;
  309. FClient.MaxHeartbeatTime = VMS_MAX_HEARTBEAT_TIME;
  310. FClient.DatagramSize = VMS_MAX_DATAGRAM_SIZE;
  311. m_DataPacketNumber = 0;
  312. m_SubscribeSerialNbr = 0;
  313. FLocalCmd.GeneralStatus = false;
  314. FLocalCmd.ModuleStatus = false;
  315. FLocalCmd.PowerStatus = false;
  316. FLocalCmd.ScreenDataStatusMessage = false;
  317. FLocalCmd.RealTimeDisplayMessage = false;
  318. m_pState->Comm = vms_error;
  319. #if 0
  320. if (m_pState != NULL)
  321. {
  322. m_pState->Cpsw.Enable = bit_enable;
  323. m_pState->CollectDate = Now().FormatString("yyyymmddhhnnss");
  324. m_pState->Door = STATE_UNKNOWN;
  325. m_pState->Heater = STATE_UNKNOWN;
  326. m_pState->Fan = STATE_UNKNOWN;
  327. m_pState->ModuleState = STATE_UNKNOWN;
  328. m_pState->Power = STATE_UNKNOWN;
  329. m_pState->Temp = 0;
  330. m_pState->Bright = 0;
  331. m_pState->ModuleHorizontal = 0;
  332. m_pState->ModuleVertical = 0;
  333. m_pState->PowerCount = 0;
  334. memset(m_pState->ModuleStatus, STATE_UNKNOWN, sizeof(m_pState->ModuleStatus));
  335. memset(m_pState->PowerStatus, STATE_UNKNOWN, sizeof(m_pState->PowerStatus));
  336. }
  337. #endif
  338. InitRx();
  339. LINFO("ClientInitInfo ok");
  340. }
  341. //---------------------------------------------------------------------------
  342. void __fastcall TVMSCThread::InitRx()
  343. {
  344. m_RxPktLen = 0;
  345. m_RxLen = 0;
  346. m_RxState = RX_STX;
  347. memset(m_RxBuff, 0x00, sizeof(m_RxBuff));
  348. }
  349. //---------------------------------------------------------------------------
  350. void __fastcall TVMSCThread::ClientTerminate(void)
  351. {
  352. try
  353. {
  354. FVmsObj->Client.Comm = state_close;
  355. FVmsObj->Client.Status = process_fail;
  356. FVmsObj->Client.pThread = NULL;
  357. FVmsObj->Client.ActiveIndicator = false;
  358. //POST_MSG(MAINHANDLE, WM_VMS_THREAD, WM_VMS_CLIENT_STTS, (int)FVmsObj);
  359. SINFO("Thread stop");
  360. }
  361. catch(Exception &e)
  362. {
  363. }
  364. }
  365. //---------------------------------------------------------------------------
  366. int HexArr2BinArr(unsigned char *AHexData, unsigned char *AResult)
  367. {
  368. //TODO: 결과를 리턴할 메모리의 크기는 체크하지 않음
  369. int nLen = 0;
  370. unsigned const char *pos = AHexData;
  371. char *endptr = NULL;
  372. int count = (strlen(AHexData) / 2);
  373. if ((AHexData[0] == NULL) || (strlen(AHexData) % 2))
  374. {
  375. //데이터가 없거나 길이가 짝수가 아닌경우
  376. return -2;
  377. }
  378. for(int ii = 0; ii < count; ii++)
  379. {
  380. char buf[5] = {'0', 'x', pos[0], pos[1], 0};
  381. AResult[nLen++] = (unsigned char)strtol(buf, &endptr, 0);
  382. pos += 2 * sizeof(char);
  383. if (endptr[0] != '\0') {
  384. //Hex 문자열이 아님
  385. return -1;
  386. }
  387. }
  388. #if 0
  389. BYTE chn, cln, val;
  390. chn = (BYTE)szData[0];
  391. cln = (BYTE)szData[1];
  392. hn = chn > '9' ? chn - 'A' + 10 : chn - '0';
  393. ln = cln > '9' ? cln - 'A' + 10 : cln - '0';
  394. val = (BYTE)((hn << 4 ) | ln);
  395. RxBuff[RxLen] = val;
  396. #endif
  397. return nLen;
  398. }
  399. //---------------------------------------------------------------------------
  400. void __fastcall TVMSCThread::Execute()
  401. {
  402. BYTE rcvBuff[DEFAULT_TCP_PACKET_MAX_SIZE];
  403. int rcvLen;
  404. int nError;
  405. int nResult;
  406. bool bError;
  407. //static bool first = true;
  408. try
  409. {
  410. NameThreadForDebugging(m_strName);
  411. FErrLine = 0;
  412. SINFO("Thread start");
  413. try
  414. {
  415. while (!Terminated && !FUserTerm && !g_AppCfg.bThrExit)
  416. {
  417. FVmsObj->Client.Status = process_run;
  418. m_pState->Comm = vms_error;
  419. SINFO("Server connect try: %s.%s", TcpClient->RemoteHost.c_str(), TcpClient->RemotePort.c_str());
  420. TcpClient->Open();
  421. bError = false;
  422. while (!Terminated && TcpClient->Connected && !FUserTerm && !g_AppCfg.bThrExit)
  423. {
  424. m_pState->Comm = vms_normal;
  425. try
  426. {
  427. if (SYS_ERR_OFFLINE == ClientStateMachine())
  428. {
  429. if (FClient.State == CT_CLOSE)
  430. {
  431. break;
  432. }
  433. }
  434. bError = false;
  435. if (TcpClient->WaitForData(100) || SocketActivity())
  436. {
  437. bError = false;
  438. memset(rcvBuff, 0, sizeof(rcvBuff));
  439. rcvLen = TcpClient->ReceiveBuf(rcvBuff, sizeof(rcvBuff));
  440. if (rcvLen > 0)
  441. {
  442. if ((nResult = RecvPacket(rcvBuff, rcvLen)) != SYS_ERR_NONE)
  443. {
  444. ProcErrorState(true, nResult);
  445. }
  446. }
  447. else
  448. {
  449. bError = true;
  450. }
  451. }
  452. if (bError)
  453. {
  454. SERROR("Socket Error[Closed]....");
  455. nError = -3;
  456. Close();
  457. }
  458. if (FVmsObj->Server.Status != process_run)
  459. {
  460. nError = -4;
  461. Close();
  462. }
  463. }
  464. catch(Exception &e)
  465. {
  466. SERROR("Thread execute exception: %s, Line: %d", AnsiString(e.Message).c_str(), FErrLine);
  467. nError = -2;
  468. Close();
  469. }
  470. }
  471. if (FClient.State == CT_CLOSE || FUserTerm || g_AppCfg.bThrExit)
  472. {
  473. nError = 0;
  474. SINFO("Thread exit catched....2");
  475. Close();
  476. break;
  477. }
  478. if (FVmsObj->Client.Status != process_stop)
  479. {
  480. Sleep(g_AppCfg.comm.nConnectWait * 1000);
  481. }
  482. }
  483. SERROR("Term: %d, Conn: %d, Err: %d, Line: %d, AppExit: %d, UserTerm: %d",
  484. Terminated, TcpClient->Connected, nError, FErrLine, g_AppCfg.bThrExit, FUserTerm);
  485. }
  486. __finally
  487. {
  488. TcpClient->Close();
  489. Terminate();
  490. FUserTerm = false;
  491. }
  492. }
  493. catch(Exception &e)
  494. {
  495. SERROR("Thread execute error: %s", AnsiString(e.Message).c_str());
  496. Terminate();
  497. }
  498. m_pState->Comm = vms_error;
  499. ClientTerminate();
  500. }
  501. //---------------------------------------------------------------------------
  502. void __fastcall TVMSCThread::DebugState()
  503. {
  504. switch(FClient.State)
  505. {
  506. case 1: break;
  507. default: break;
  508. }
  509. }
  510. //---------------------------------------------------------------------------
  511. bool __fastcall TVMSCThread::IsCommandTimeout()
  512. {
  513. // 마지막 전송시각이 타임아웃 시각보다 큰경우
  514. return CommUtil_TimeDiff(FClient.sendTimer) > FClient.TimeOut ? true : false;
  515. }
  516. //---------------------------------------------------------------------------
  517. /*
  518. * 클라이언트 상태에 따른 처리
  519. * arguments
  520. * void
  521. * return
  522. * void
  523. */
  524. int __fastcall TVMSCThread::ClientStateMachine(void)
  525. {
  526. FErrLine = 13;
  527. int result;
  528. bool bRequest;
  529. result = SYS_ERR_NONE;
  530. // CMDTIMEOUT 체크
  531. // 현재 수신데이터가 있고 마지막 수진시각이 타임아웃보다 크면
  532. // 수신 타임아웃으로 처리한다.
  533. if (m_RxLen && (CommUtil_TimeDiff(m_rcvPacketTimer) > FClient.TimeOut))
  534. {
  535. InitRx();
  536. m_RxLen = 0;
  537. ProcErrorState(true, SYS_ERR_RECEIVE_TIMEOUT);
  538. return result;
  539. }
  540. DebugState();
  541. switch(FClient.State)
  542. {
  543. case CT_CLOSE:
  544. LERROR("STATE: CT_CLOSE");
  545. Terminate();
  546. result = SYS_ERR_OFFLINE;
  547. break;
  548. case CT_IDLE:
  549. FClient.reqStatusTimer = Now() - ITSCOMM_SECTIME(CLIENT_CONNECT_RETRY_TIME - CLIENT_CHANGE_TIME);
  550. FClient.State = CT_SECTION;
  551. break;
  552. case CT_SECTION:
  553. #if 0
  554. if (CommUtil_TimeDiff(m_WatchDogTimer) > g_AppCfg.comm.nWatchDogTime)
  555. {
  556. LERROR("STATE: ST_SECTION - WatchDog Time over");
  557. FClient.State = CT_CLOSE;
  558. break;
  559. }
  560. #endif
  561. if (CommUtil_TimeDiff(FClient.reqStatusTimer) > FClient.pollingCycleTime)
  562. {
  563. FClient.reqStatusTimer = Now();
  564. FLocalCmd.GeneralStatus = false;
  565. FLocalCmd.ModuleStatus = false;
  566. FLocalCmd.PowerStatus = false;
  567. }
  568. FClient.State = CT_LOCAL_COMMAND;
  569. break;
  570. case CT_LOCAL_COMMAND:
  571. result = CheckLocalData(bRequest);
  572. if (bRequest)
  573. {
  574. if (result == SYS_ERR_NONE) FClient.State = CT_LOCAL_WAIT;
  575. else
  576. {
  577. if (--FClient.sendRetry <= 0) FClient.State = CT_CLOSE;
  578. }
  579. }
  580. else FClient.State = CT_CLIENT_COMMAND;
  581. break;
  582. case CT_CLIENT_COMMAND:
  583. result = CheckClientData(bRequest);
  584. if (bRequest)
  585. {
  586. if (result == SYS_ERR_NONE) FClient.State = CT_CLIENT_WAIT;
  587. else
  588. {
  589. if (--FClient.sendRetry <= 0) FClient.State = CT_CLOSE;
  590. }
  591. }
  592. else FClient.State = CT_SECTION;
  593. break;
  594. case CT_CLIENT_WAIT:
  595. case CT_LOCAL_WAIT:
  596. if (IsCommandTimeout())
  597. {
  598. // Local Command에 대한 타임아웃이 발생한 경우
  599. if (FClient.sendRetry > 0)
  600. {
  601. // 타임아웃 카운트 보다 작을 경우 Command를 전송한다.
  602. if (FClient.State == CT_CLIENT_WAIT) FClient.State = CT_CLIENT_COMMAND;
  603. else
  604. if (FClient.State == CT_LOCAL_WAIT) FClient.State = CT_LOCAL_COMMAND;
  605. }
  606. else
  607. {
  608. // 타임아웃 카운트 보다 큰 경우 종료
  609. FClient.State = CT_CLOSE;
  610. }
  611. }
  612. break;
  613. default:
  614. FClient.State = CT_IDLE;
  615. break;
  616. }
  617. if (result)
  618. {
  619. ProcErrorState(false, result);
  620. }
  621. return result;
  622. }
  623. //---------------------------------------------------------------------------
  624. /*
  625. * 프로세스 자체(주기)적으로 VMS로 전송(요청)되어야 할 패킷이 있는지 확인하고 처리한다.
  626. * arguments
  627. * void
  628. * return
  629. * void
  630. */
  631. int __fastcall TVMSCThread::CheckLocalData(bool &ARequest)
  632. {
  633. int result = SYS_ERR_NONE;
  634. COMMAND_ARGUMENT arg;
  635. memset(&arg, 0x00, sizeof(arg));
  636. FLocalCmd.OpCode = 0x00;
  637. FLocalCmd.obj = OBJ_None; /* EN_OBJECT_ID */
  638. FLocalCmd.DataPacketNumber = 0; /* DataPacket Number */
  639. FLocalCmd.Idx = 0;
  640. ARequest = true;
  641. /* 상태정보 요청 확인 */
  642. if (FLocalCmd.GeneralStatus == false)
  643. {
  644. //LINFO("**** REQ_VMS_STATUS");
  645. arg.Subscription.nbr = NBR_GENERAL_STATUS;
  646. //arg.Subscription.mode = SubscriptionMode_PR_single;
  647. arg.Subscription.delay = 60;
  648. arg.Subscription.obj = OBJ_GeneralStatus;
  649. FLocalCmd.OpCode = REQ_VMS_STATUS;
  650. FLocalCmd.obj = OBJ_GeneralStatus;
  651. FLocalCmd.DataPacketNumber = m_DataPacketNumber;
  652. result = ProcessSendPacket(FLocalCmd.OpCode, &arg);
  653. return result;
  654. }
  655. // 모듈상태 요청 확인
  656. if (FLocalCmd.ModuleStatus == false)
  657. {
  658. //LINFO("**** REQ_VMS_MODULE_STATUS");
  659. arg.Subscription.nbr = NBR_MODULE_STATUS;
  660. //arg.Subscription.mode = SubscriptionMode_PR_single;
  661. arg.Subscription.delay = 60;
  662. arg.Subscription.obj = OBJ_ModuleStatus;
  663. FLocalCmd.OpCode = REQ_VMS_MODULE_STATUS;
  664. FLocalCmd.obj = OBJ_ModuleStatus;
  665. FLocalCmd.DataPacketNumber = m_DataPacketNumber;
  666. result = ProcessSendPacket(FLocalCmd.OpCode, &arg);
  667. return result;
  668. }
  669. // FORM 다운로드
  670. if (FVmsObj->CTLMODE->Enable == object_enable)
  671. {
  672. m_pVmsFormList->Lock();
  673. try
  674. {
  675. int nFormCnt = m_pVmsFormList->Count();
  676. for (int ii = 0; ii < nFormCnt; ii++)
  677. {
  678. TVmsForm *pVmsForm = m_pVmsFormList->GetItem(ii);
  679. if (pVmsForm)
  680. {
  681. if (pVmsForm->SvcRes == false)
  682. {
  683. arg.Publication.SubscribeSerialNbr = NBR_BASE_REALTIMEDISPLAY;
  684. arg.Publication.obj = OBJ_RealTimeDisplay;
  685. arg.Publication.Data.Form.Idx = 0;
  686. FLocalCmd.OpCode = REQ_VMS_MSG_DOWNLOAD;//REQ_VMS_LIB_DOWNLOAD;//REQ_VMS_MSG_DOWNLOAD;
  687. FLocalCmd.obj = OBJ_RealTimeDisplay;
  688. FLocalCmd.DataPacketNumber = 0;
  689. FLocalCmd.Idx = nFormCnt;
  690. break;
  691. }
  692. }
  693. }
  694. arg.Publication.Data.Form.Mode = FVmsObj->CTLMODE->Control;
  695. }
  696. __finally
  697. {
  698. m_pVmsFormList->UnLock();
  699. }
  700. if (FLocalCmd.OpCode != 0x00)
  701. {
  702. result = ProcessSendPacket(FLocalCmd.OpCode, &arg);
  703. return result;
  704. }
  705. }
  706. ARequest = false;
  707. return result;
  708. }
  709. //---------------------------------------------------------------------------
  710. /*
  711. *
  712. * arguments
  713. * void
  714. * return
  715. * void
  716. */
  717. int __fastcall TVMSCThread::CheckClientData(bool &ARequest)
  718. {
  719. FErrLine = 24;
  720. int nResult = VERR_NONE;
  721. IPCUDPPACKET *pPI = NULL;
  722. TList *pPackQueue;
  723. COMMAND_ARGUMENT arg;
  724. ARequest = false;
  725. try
  726. {
  727. pPackQueue = FVmsObj->pPackQueue->LockList();
  728. int nCmdCnt = pPackQueue->Count;
  729. for (int ii = nCmdCnt-1; ii >= 0; ii--)
  730. {
  731. pPI = (IPCUDPPACKET *)pPackQueue->Items[ii];
  732. if (pPI->Data == NULL)
  733. {
  734. delete pPI;
  735. pPackQueue->Delete(ii);
  736. continue;
  737. }
  738. memset((char*)&FCliCmd, 0x00, sizeof(FCliCmd));
  739. memset((char*)&arg, 0x00, sizeof(arg));
  740. FCliCmd.OpCode = 0x00;
  741. FCliCmd.obj = OBJ_None; /* EN_OBJECT_ID */
  742. FCliCmd.DataPacketNumber = 0; /* DataPacket Number */
  743. FCliCmd.Idx = 0;
  744. INT_VMS_POWER_CTL_REQ *pHd = (INT_VMS_POWER_CTL_REQ*)pPI->Data;
  745. memcpy(FCliCmd.VmsId, pHd->VmsId, INT_VMS_MAX_ID);
  746. memcpy(FCliCmd.OperId, pHd->OperId, INT_VMS_MAX_OPER_ID);
  747. memcpy(FCliCmd.CmdTime, pHd->CmdTime, INT_VMS_MAX_DATETIME);
  748. FCliCmd.Result = CTL_RESULT_FAIL;
  749. switch(pPI->OPCode)
  750. {
  751. case INT_OP_VMS_POWER_CTL:
  752. {
  753. INT_VMS_POWER_CTL_REQ *pReq = (INT_VMS_POWER_CTL_REQ*)pPI->Data;
  754. FCliCmd.OpCode = REQ_SIGNBOARD_POWER_CONTROL;
  755. arg.Publication.SubscribeSerialNbr = NBR_MODULE_POWER;
  756. arg.Publication.obj = OBJ_StatusControl;
  757. arg.Publication.Data.Ctl = (pReq->Command == vms_board_power_on) ? 0x01 : 0x00;
  758. }
  759. break;
  760. case INT_OP_VMS_RESET:
  761. {
  762. INT_VMS_RESET_REQ *pReq = (INT_VMS_RESET_REQ*)pPI->Data;
  763. FCliCmd.OpCode = REQ_VMS_INITIALIZE;
  764. }
  765. break;
  766. case INT_OP_VMS_DIRECT:
  767. {
  768. INT_VMS_DIRECT_CTL_REQ *pReq = (INT_VMS_DIRECT_CTL_REQ*)pPI->Data;
  769. FCliCmd.OpCode = pReq->Command;
  770. }
  771. break;
  772. case INT_OP_VMS_LUMINANCE_CTL:
  773. {
  774. INT_VMS_LUMINANCE_REQ *pReq = (INT_VMS_LUMINANCE_REQ*)pPI->Data;
  775. arg.Publication.SubscribeSerialNbr = NBR_LUMINANCE;
  776. arg.Publication.obj = OBJ_StatusControl;
  777. arg.Publication.Data.Ctl = pReq->Luminance;
  778. FCliCmd.OpCode = REQ_VMS_LUMINANCE_LEVEL_SET;
  779. }
  780. break;
  781. case INT_OP_VMS_PARA_SET2:
  782. {
  783. INT_VMS_PARA_SET_REQ2 *pReq = (INT_VMS_PARA_SET_REQ2*)pPI->Data;
  784. memcpy(FCliCmd.VmsId, pReq->VmsId, INT_VMS_MAX_ID);
  785. memcpy(FCliCmd.OperId, pReq->OperId, INT_VMS_MAX_OPER_ID);
  786. memcpy(FCliCmd.CmdTime, pReq->CmdTime, INT_VMS_MAX_DATETIME);
  787. arg.Publication.SubscribeSerialNbr = NBR_STATUS_SETTING;
  788. arg.Publication.obj = OBJ_StatusSetting;
  789. arg.Publication.Data.Set2.DefCommErr = pReq->DefCommErr; // 통신장애 기본값, 제어기가 Host로부터 Poll 또는 명령을 받지 않고 경과할 수 있는 최대시간 (default ; 60초)
  790. arg.Publication.Data.Set2.SlotCommErr = pReq->SlotCommErr; // 통신장애 slot번호, 통신 fail 시 표시할 메시지 번호(default 0번)
  791. arg.Publication.Data.Set2.SlotPowerErr = pReq->SlotPowerErr; // 전원장애 slot번호, 전원장애 시 표시할 메시지 번호(default 0번)
  792. arg.Publication.Data.Set2.NightLuminance = pReq->NightLuminance; // 야간 휘도 값, 0x30 ~ 0x3F
  793. arg.Publication.Data.Set2.DayLuminance = pReq->DayLuminance; // 주간 휘도 값, 0x40 ~ 0x4F
  794. arg.Publication.Data.Set2.PhaseCycleTime = pReq->PhaseCycleTime; // phase시간주기, 장애시 phase주기 (default : 3초, 범위 : 0 ~ 10초)
  795. arg.Publication.Data.Set2.ModuleFailRate = pReq->ModuleFailRate; // 모듈장애율, 한개의 module을 장애로 처리하기 위한 장애 pixel백분율 (default 10%)
  796. arg.Publication.Data.Set2.ModuleCheckTime = pReq->ModuleCheckTime; // 모듈감시 주기, 0 ~ 255 (단위:초)
  797. arg.Publication.Data.Set2.BoardOnHour = pReq->BoardOnHour; // 전광판 On time(시), 0시 ~ 23시
  798. arg.Publication.Data.Set2.BoardOnMin = pReq->BoardOnMin; // 전광판 On time(분), 0시 ~ 23시
  799. arg.Publication.Data.Set2.BoardOffHour = pReq->BoardOffHour; // 전광판 Off time(시), 0시 ~ 23시
  800. arg.Publication.Data.Set2.BoardOffMin = pReq->BoardOffMin; // 전광판 Off time(분), 0시 ~ 23시
  801. FVmsObj->VMS_CMNC_ERR_BASS_VAL = (int)pReq->DefCommErr;
  802. FVmsObj->CMNCFAIL_SLOT_NMBR = (int)pReq->SlotCommErr; // NUMBER(4) Y 0 통신장애 SLOT 번호
  803. FVmsObj->PWER_FAIL_SLOT_NMBR = (int)pReq->SlotPowerErr; // NUMBER(4) Y 0 전원 장애 SLOT 번호
  804. FVmsObj->VMS_NGHT_BRGH_STEP = (int)pReq->NightLuminance;
  805. FVmsObj->VMS_WEEK_BRGH_STEP = (int)pReq->DayLuminance;
  806. //FVmsObj->VMS_PHSE_CHNG_CYCL = (int)pReq->PhaseCycleTime;
  807. FVmsObj->VMS_MODL_ERR_RATE = (int)pReq->ModuleFailRate;
  808. FVmsObj->VMS_MODL_CHK_CYCL = (int)pReq->ModuleCheckTime;
  809. //m_State.ModuleOperatingTemperature = FVmsObj->VMS_CMNC_ERR_BASS_VAL; /* 필수 모듈 전원이 꺼지는 온도값(℃) */
  810. #if 0
  811. AnsiString sOn, sOff;
  812. sOn.printf("%02d%02d", (int)pReq->BoardOnHour, (int)pReq->BoardOnMin);
  813. sOff.printf("%02d%02d", (int)pReq->BoardOffHour, (int)pReq->BoardOffMin);
  814. FVmsObj->MODULE.PowerOnTime = Now().FormatString("yyyymmdd") + sOn;
  815. FVmsObj->MODULE.PowerOffTime = Now().FormatString("yyyymmdd") + sOff;
  816. #endif
  817. FCliCmd.OpCode = REQ_VMS_PARAM_DOWNLOAD;
  818. }
  819. break;
  820. #if 0
  821. case INT_OP_VMS_PARA_SET:
  822. {
  823. INT_VMS_PARA_SET_REQ *pReq = (INT_VMS_PARA_SET_REQ*)pPI->Data;
  824. memcpy(FCliCmd.VmsId, pReq->VmsId, INT_VMS_MAX_ID);
  825. memcpy(FCliCmd.OperId, pReq->OperId, INT_VMS_MAX_OPER_ID);
  826. memcpy(FCliCmd.CmdTime, pReq->CmdTime, INT_VMS_MAX_DATETIME);
  827. arg.Publication.SubscribeSerialNbr = NBR_STATUS_SETTING;
  828. arg.Publication.obj = OBJ_StatusSetting;
  829. arg.Publication.Data.Set.SchMsgTime = (int)pReq->SchMsgTime;
  830. arg.Publication.Data.Set.ModuleTemp = (int)pReq->ModuleTemp;
  831. arg.Publication.Data.Set.FanTemp = (int)pReq->FanTemp;
  832. arg.Publication.Data.Set.HeaterTemp = (int)pReq->HeaterTemp;
  833. arg.Publication.Data.Set.ModuleFail = (int)pReq->ModuleFail;
  834. arg.Publication.Data.Set.RetryCount = (int)pReq->RetryCount;
  835. arg.Publication.Data.Set.TimeOut = (int)pReq->TimeOut;
  836. FCliCmd.Data.Para.SchMsgTime = (int)pReq->SchMsgTime;
  837. FCliCmd.Data.Para.ModuleTemp = (int)pReq->ModuleTemp;
  838. FCliCmd.Data.Para.FanTemp = (int)pReq->FanTemp;
  839. FCliCmd.Data.Para.HeaterTemp = (int)pReq->HeaterTemp;
  840. FCliCmd.Data.Para.ModuleFail = (int)pReq->ModuleFail;
  841. FCliCmd.Data.Para.RetryCount = (int)pReq->RetryCount;
  842. FCliCmd.Data.Para.TimeOut = (int)pReq->TimeOut;
  843. FCliCmd.OpCode = CTL_TYPE_PARA_SET;
  844. FCliCmd.obj = AI_StatusSettingMessage;
  845. }
  846. break;
  847. #endif
  848. default:
  849. nResult = VERR_UNKNOWN_COMMAND;
  850. break;
  851. }
  852. if (nResult == VERR_NONE)
  853. {
  854. nResult = ProcessSendPacket(FCliCmd.OpCode, &arg);
  855. }
  856. //ClientResponse(nResult);
  857. if (pPI->Size > 0)
  858. {
  859. delete []pPI->Data;
  860. }
  861. delete pPI;
  862. pPI = NULL;
  863. pPackQueue->Delete(ii);
  864. ARequest = true;
  865. break;
  866. }
  867. }
  868. __finally
  869. {
  870. FVmsObj->pPackQueue->UnlockList();
  871. }
  872. return nResult;
  873. }
  874. //---------------------------------------------------------------------------
  875. void __fastcall TVMSCThread::ClientResponse(int error)
  876. {
  877. #ifdef CENTERCOMM
  878. BYTE ErrCode;
  879. int sResult;
  880. int Flag;
  881. bool bSave = false;
  882. switch(error)
  883. {
  884. case SYS_ERR_NONE: break;
  885. case SYS_ERR_OTHER: ErrCode = INT_ERROR_OTHER; break;
  886. case SYS_ERR_INTERNAL: ErrCode = INT_ERROR_SYSTEM; break;
  887. case SYS_ERR_MEMORY: ErrCode = INT_ERROR_SYSTEM; break;
  888. case SYS_ERR_DATABASE: ErrCode = INT_ERROR_SYSTEM; break;
  889. case SYS_ERR_RESET: ErrCode = INT_ERROR_SYSTEM; break;
  890. case SYS_ERR_START: ErrCode = INT_ERROR_SYSTEM; break;
  891. case SYS_ERR_OFFLINE: ErrCode = INT_ERROR_OFFLINE; break;
  892. case SYS_ERR_NO_RES: ErrCode = INT_ERROR_NO_RESPONSE; break;
  893. case SYS_ERR_ACCESS: ErrCode = INT_ERROR_PROCESS; break;
  894. case SYS_ERR_INVALID: ErrCode = INT_ERROR_OTHER; break;
  895. case SYS_ERR_UNKNOWN: ErrCode = INT_ERROR_UNKNOWN_CODE; break;
  896. case SYS_ERR_WRITE_LENGTH: ErrCode = INT_ERROR_OTHER; break;
  897. case SYS_ERR_PACKET_SIZE_LARGE: ErrCode = INT_ERROR_OTHER; break;
  898. case SYS_ERR_INVALID_TAG: ErrCode = INT_ERROR_OTHER; break;
  899. case SYS_ERR_CRC: ErrCode = INT_ERROR_OTHER; break;
  900. case SYS_ERR_LENGTH: ErrCode = INT_ERROR_LENGTH; break;
  901. case SYS_ERR_ADDRESS: ErrCode = INT_ERROR_ADDRESS; break;
  902. case SYS_ERR_HEADER_OPTIONS: ErrCode = INT_ERROR_HEADER; break;
  903. case SYS_ERR_UNKNOWN_COMMAND: ErrCode = INT_ERROR_UNKNOWN_OPCODE; break;
  904. case SYS_ERR_RECEIVE_TIMEOUT: ErrCode = INT_ERROR_OTHER; break;
  905. case SYS_ERR_DATA_SIZE: ErrCode = INT_ERROR_DISCORD; break;
  906. case SYS_ERR_MISMATCH: ErrCode = INT_ERROR_OTHER; break;
  907. case SYS_ERR_INVALID_PARA: ErrCode = INT_ERROR_INVALID_DATA; break;
  908. case SYS_ERR_MOVEMENT: ErrCode = INT_ERROR_MOVEMENT; break;
  909. case SYS_ERR_UNAUTHORIZED: ErrCode = INT_ERROR_UNAUTHORIZED; break;
  910. default: ErrCode = INT_ERROR_OTHER; break;
  911. }
  912. switch (m_Req.OpCode)
  913. {
  914. case INT_OP_VMS_POWER_CTL: /* 0x0303 VMS 통신 서버, VMS 전광판 On/Off 제어 */
  915. if (error == SYS_ERR_NONE)
  916. {
  917. Flag = SEND_ACK;
  918. m_Set.Data.Control.Result = CTL_RESULT_SUCC;
  919. }
  920. else
  921. {
  922. Flag = SEND_NACK;
  923. }
  924. bSave = true;
  925. break;
  926. case INT_OP_VMS_PARA_SET: /* 0x0308 VMS 통신 서버, VMS 환경설정정보 전송 */
  927. if (error == SYS_ERR_NONE)
  928. {
  929. Flag = SEND_ACK;
  930. bSave = true;
  931. }
  932. else
  933. {
  934. Flag = SEND_NACK;
  935. }
  936. break;
  937. case INT_OP_VMS_RESET: /* 0x0309 VMS 통신 서버, VMS 제어기 리셋 전송 */
  938. if (error == SYS_ERR_NONE)
  939. {
  940. Flag = SEND_ACK;
  941. m_Set.Data.Control.Result = CTL_RESULT_SUCC;
  942. }
  943. else
  944. {
  945. Flag = SEND_NACK;
  946. }
  947. bSave = true;
  948. break;
  949. default:
  950. Flag = SEND_NONE;
  951. break;
  952. }
  953. if (bSave == true)
  954. {
  955. if ((sResult = SendDbThreadDataMessage(WM_DATA_SAVE, (void *)&m_Set, sizeof(m_Set))) != SYS_ERR_NONE)
  956. {
  957. }
  958. }
  959. if (Flag == SEND_ACK)
  960. {
  961. INT_ACK_RES Ack;
  962. memset(&Ack, 0x00, sizeof(Ack));
  963. Ack.OPCode.Type = INT_TYPE(m_Req.OpCode);
  964. Ack.OPCode.Kind = INT_KIND(m_Req.OpCode);
  965. Ack.MsgSeq = m_Req.MsgSeq;
  966. if ((sResult = AckRes(&Ack, m_Req.ProcessID)) != UDP_ERR_NONE)
  967. {
  968. }
  969. }
  970. else
  971. if (Flag == SEND_NACK)
  972. {
  973. INT_NACK_RES Nack;
  974. memset(&Nack, 0x00, sizeof(Nack));
  975. Nack.OPCode.Type = INT_TYPE(m_Req.OpCode);
  976. Nack.OPCode.Kind = INT_KIND(m_Req.OpCode);
  977. Nack.MsgSeq = m_Req.MsgSeq;
  978. Nack.ErrCode = ErrCode;
  979. if ((sResult = NackRes(&Nack, m_Req.ProcessID)) != UDP_ERR_NONE)
  980. {
  981. }
  982. }
  983. #endif
  984. }
  985. //---------------------------------------------------------------------------
  986. int __fastcall TVMSCThread::SendDbThreadMessage(UINT Msg, int wParam, int lParam)
  987. {
  988. int result;
  989. result = SYS_ERR_OTHER;
  990. if (g_SysInfo->State.CommThreadID != NULL)
  991. {
  992. if (PostThreadMessage(g_SysInfo->State.CommThreadID, Msg, (WPARAM)wParam, (LPARAM)lParam))
  993. {
  994. result = SYS_ERR_NONE;
  995. }
  996. else
  997. {
  998. result = SYS_ERR_INTERNAL;
  999. }
  1000. }
  1001. return result;
  1002. }
  1003. //---------------------------------------------------------------------------
  1004. int __fastcall TVMSCThread::SendDbThreadDataMessage(UINT Msg, void *pData, int iLen)
  1005. {
  1006. int nResult;
  1007. char *p;
  1008. nResult = VERR_OTHER;
  1009. if (g_SysInfo->State.CommThreadID != NULL)
  1010. {
  1011. p = new char[iLen];
  1012. if (p != NULL)
  1013. {
  1014. try
  1015. {
  1016. memcpy(p, pData, iLen);
  1017. if (PostThreadMessage(g_SysInfo->State.CommThreadID, Msg, (WPARAM)p, NULL))
  1018. {
  1019. nResult = VERR_NONE;
  1020. Sleep(50);
  1021. }
  1022. else
  1023. {
  1024. nResult = VERR_INTERNAL;
  1025. }
  1026. }
  1027. __finally
  1028. {
  1029. if (nResult != VERR_NONE)
  1030. {
  1031. delete []p;
  1032. }
  1033. }
  1034. }
  1035. else
  1036. {
  1037. nResult = VERR_MEMORY_ALLOC;
  1038. }
  1039. }
  1040. return nResult;
  1041. }
  1042. //---------------------------------------------------------------------------
  1043. /*
  1044. * 에러 처리
  1045. * arguments
  1046. * void
  1047. * return
  1048. * void
  1049. */
  1050. int __fastcall TVMSCThread::ProcErrorState(bool flag, int result)
  1051. {
  1052. FErrLine = 14;
  1053. #if 1
  1054. {
  1055. AnsiString strLog;
  1056. switch(result)
  1057. {
  1058. case SYS_ERR_NONE: strLog.sprintf("no error [%d]", result); break;
  1059. case SYS_ERR_OTHER: strLog.sprintf("other [%d]", result); break;
  1060. case SYS_ERR_INTERNAL: strLog.sprintf("internal system error(kernel..) [%d]", result); break;
  1061. case SYS_ERR_MEMORY: strLog.sprintf("memory overflow [%d]", result); break;
  1062. case SYS_ERR_DATABASE: strLog.sprintf("system database error [%d]", result); break;
  1063. case SYS_ERR_RESET: strLog.sprintf("system reset [%d]", result); break;
  1064. case SYS_ERR_START: strLog.sprintf("system start [%d]", result); break;
  1065. case SYS_ERR_OFFLINE: strLog.sprintf("offline [%d]", result); break;
  1066. case SYS_ERR_NO_RES: strLog.sprintf("no response [%d]", result); break;
  1067. case SYS_ERR_ACCESS: strLog.sprintf("access denied [%d]", result); break;
  1068. case SYS_ERR_INVALID: strLog.sprintf("invalid data type [%d]", result); break;
  1069. case SYS_ERR_UNKNOWN: strLog.sprintf("unknown data type [%d]", result); break;
  1070. case SYS_ERR_WRITE_LENGTH: strLog.sprintf("write length [%d]", result); break;
  1071. case SYS_ERR_PACKET_SIZE_LARGE: strLog.sprintf("packet size large [%d]", result); break;
  1072. case SYS_ERR_INVALID_TAG: strLog.sprintf("invalid tag [%d]", result); break;
  1073. case SYS_ERR_CRC: strLog.sprintf("crc [%d]", result); break;
  1074. case SYS_ERR_LENGTH: strLog.sprintf("length [%d]", result); break;
  1075. case SYS_ERR_ADDRESS: strLog.sprintf("address [%d]", result); break;
  1076. case SYS_ERR_HEADER_OPTIONS: strLog.sprintf("header options [%d]", result); break;
  1077. case SYS_ERR_UNKNOWN_COMMAND: strLog.sprintf("unknown command [%d]", result); break;
  1078. case SYS_ERR_RECEIVE_TIMEOUT: strLog.sprintf("receive timeout [%d]", result); break;
  1079. case SYS_ERR_DATA_SIZE: strLog.sprintf("data size [%d]", result); break;
  1080. case SYS_ERR_MISMATCH: strLog.sprintf("mismatch command [%d]", result); break;
  1081. case SYS_ERR_INVALID_PARA: strLog.sprintf("invalid parameter [%d]", result); break;
  1082. case SYS_ERR_MOVEMENT: strLog.sprintf("movement [%d]", result); break;
  1083. case SYS_ERR_UNAUTHORIZED: strLog.sprintf("unauthorized [%d]", result); break;
  1084. case SYS_ERR_DATEXDATAPACKET_DECODE: strLog.sprintf("DatexDataPacket decode [%d]", result); break;
  1085. case SYS_ERR_INVALID_VERSION_NUMBER: strLog.sprintf("invalid version number [%d]", result); break;
  1086. case SYS_ERR_C2CAUTHENTICATEDMESSAGE_DECODE: strLog.sprintf("C2CAuthenticatedMessage decode [%d]", result); break;
  1087. case SYS_ERR_C2CAUTHENTICATEDMESSAGE: strLog.sprintf("C2CAuthenticatedMessage [%d]", result); break;
  1088. case SYS_ERR_NOT_LOGIN: strLog.sprintf("Not login [%d]", result); break;
  1089. case SYS_ERR_ACCEPT_TYPE: strLog.sprintf("Accept Type [%d]", result); break;
  1090. case SYS_ERR_DATEXPUBLISH_FORMAT: strLog.sprintf("datexPublish Format [%d]", result); break;
  1091. case SYS_ERR_DATEXPUBLISH_TYPE: strLog.sprintf("datexPublish Type [%d]", result); break;
  1092. case SYS_ERR_UNKNOWN_MESSAGE_ID: strLog.sprintf("unknown Message id [%d]", result); break;
  1093. case SYS_ERR_MESSAGE_DECODE: strLog.sprintf("Message decode [%d]", result); break;
  1094. case SYS_ERR_DATEXDATAPACKET_ENCODE: strLog.sprintf("DatexDataPacket encode [%d]", result); break;
  1095. case SYS_ERR_C2CAUTHENTICATEDMESSAGE_ENCODE: strLog.sprintf("C2CAuthenticatedMessage encode [%d]", result); break;
  1096. case SYS_ERR_MESSAGE_ENCODE: strLog.sprintf("Message encode [%d]", result); break;
  1097. case SYS_ERR_PUBLICATIONDATA_ENCODE: strLog.sprintf("PublicationData encode [%d]", result); break;
  1098. case SYS_ERR_MISMATCH_DESTINATION_TEXT: strLog.sprintf("mismatch Destination text [%d]", result); break;
  1099. case SYS_ERR_DATEXLOGIN_VALUE: strLog.sprintf("Login Value [%d]", result); break;
  1100. case SYS_ERR_SUBSCRIPTION_TYPE: strLog.sprintf("SubscriptionType Type [%d]", result); break;
  1101. case SYS_ERR_SUBSCRIPTION_STATUS_VALUE: strLog.sprintf("SubscriptionType Status Value [%d]", result); break;
  1102. case SYS_ERR_SUBSCRIPTION_MODE_VALUE: strLog.sprintf("SubscriptionType Mode Value [%d]", result); break;
  1103. case SYS_ERR_SUBSCRIPTION_FORMAT_VALUE: strLog.sprintf("SubscriptionType Format Value [%d]", result); break;
  1104. case SYS_ERR_HANGUL_CONVERSION: strLog.sprintf("Hangul Conversion [%d]", result); break;
  1105. case SYS_ERR_INVALID_TAGANDLEN: strLog.sprintf("invalid Tag And Len [%d]", result); break;
  1106. case SYS_ERR_PUBLICATIONDATA_DECODE: strLog.sprintf("PublicationData decode [%d]", result); break;
  1107. default: strLog.sprintf("Unknown Error [%d]", result); break;
  1108. }
  1109. if (flag){
  1110. LERROR("Recv Error %s", strLog.c_str());
  1111. }else{
  1112. LERROR("Send Error %s", strLog.c_str());
  1113. }
  1114. }
  1115. #endif
  1116. return 0;
  1117. }
  1118. //---------------------------------------------------------------------------
  1119. /*
  1120. * 상태 변경
  1121. * arguments
  1122. * void
  1123. * return
  1124. * void
  1125. */
  1126. int __fastcall TVMSCThread::SetClientState(int ACase)
  1127. {
  1128. FErrLine = 15;
  1129. switch(FClient.State)
  1130. {
  1131. case CT_LOGIN_WAIT:
  1132. if (ACase == SET_CLIENT_SUCC)
  1133. {
  1134. if (FVmsObj->FIsOldProtocol)
  1135. {
  1136. //정보요청을 등록해야함(기존 VMS)
  1137. FClient.State = CT_SECTION;//CT_REGIST; //TODO
  1138. FClient.reqStatusTimer = Now() - ITSCOMM_SECTIME(FClient.pollingCycleTime);
  1139. }
  1140. else
  1141. {
  1142. FClient.State = CT_SECTION;
  1143. FClient.reqStatusTimer = Now() - ITSCOMM_SECTIME(FClient.pollingCycleTime);
  1144. }
  1145. }
  1146. else
  1147. if (ACase == SET_CLIENT_FAIL)
  1148. {
  1149. FClient.State = CT_IDLE;
  1150. }
  1151. break;
  1152. case CT_FRED_WAIT:
  1153. FClient.State = CT_SECTION;
  1154. break;
  1155. case CT_LOCAL_WAIT:
  1156. if (ACase == SET_CLIENT_SUCC)
  1157. {
  1158. FClient.State = CT_LOCAL_COMMAND;//CT_CLIENT_COMMAND;
  1159. }
  1160. else
  1161. if (ACase == SET_CLIENT_FAIL)
  1162. {
  1163. FClient.State = CT_LOCAL_COMMAND;
  1164. }
  1165. break;
  1166. case CT_CLIENT_WAIT:
  1167. if (ACase == SET_CLIENT_SUCC)
  1168. {
  1169. FClient.State = CT_SECTION;
  1170. }
  1171. else
  1172. if (ACase == SET_CLIENT_FAIL)
  1173. {
  1174. FClient.State = CT_CLIENT_COMMAND;
  1175. }
  1176. break;
  1177. case CT_REGIST_WAIT:
  1178. if (ACase == SET_CLIENT_SUCC)
  1179. {
  1180. FClient.State = CT_REGIST_COMMAND;
  1181. }
  1182. else
  1183. if (ACase == SET_CLIENT_FAIL)
  1184. {
  1185. FClient.State = CT_CLIENT_COMMAND;
  1186. }
  1187. break;
  1188. default:
  1189. break;
  1190. }
  1191. return 0;
  1192. }
  1193. //---------------------------------------------------------------------------
  1194. void __fastcall TVMSCThread::InfoPacket(BYTE *ABuff, int ALen, bool ASend, int AResult/*=0*/)
  1195. {
  1196. VMS_PACKET *Pkt = (VMS_PACKET*)ABuff;
  1197. AnsiString sCmd = "";
  1198. ACK_NAK res;
  1199. bool acknak = true;
  1200. switch(Pkt->hd.OpCode)
  1201. {
  1202. case REQ_VMS_STATUS:
  1203. acknak = false;
  1204. if (ASend) sCmd = "REQ_VMS_STATUS";
  1205. else sCmd = "RES_VMS_STATUS";
  1206. break;
  1207. case REQ_VMS_MSG_DOWNLOAD:
  1208. if (ASend) sCmd = "REQ_VMS_MSG_DOWNLOAD";
  1209. else sCmd = "RES_VMS_MSG_DOWNLOAD";
  1210. break;
  1211. case REQ_VMS_LIB_DOWNLOAD:
  1212. if (ASend) sCmd = "REQ_VMS_LIB_DOWNLOAD";
  1213. else sCmd = "RES_VMS_LIB_DOWNLOAD";
  1214. break;
  1215. case REQ_VMS_PARAM_DOWNLOAD:
  1216. if (ASend) sCmd = "REQ_VMS_PARAM_DOWNLOAD";
  1217. else sCmd = "RES_VMS_PARAM_DOWNLOAD";
  1218. break;
  1219. case REQ_VMS_BLANK_DISP:
  1220. if (ASend) sCmd = "REQ_VMS_BLANK_DISP";
  1221. else sCmd = "RES_VMS_BLANK_DISP";
  1222. break;
  1223. case REQ_VMS_DEF_MSG_DISP:
  1224. if (ASend) sCmd = "REQ_VMS_DEF_MSG_DISP";
  1225. else sCmd = "RES_VMS_DEF_MSG_DISP";
  1226. break;
  1227. case REQ_VMS_MODULE_STATUS:
  1228. acknak = false;
  1229. if (ASend) sCmd = "REQ_VMS_MODULE_STATUS";
  1230. else sCmd = "RES_VMS_MODULE_STATUS";
  1231. break;
  1232. case REQ_VMS_INITIALIZE:
  1233. if (ASend) sCmd = "REQ_VMS_INITIALIZE";
  1234. else sCmd = "RES_VMS_INITIALIZE";
  1235. break;
  1236. case REQ_VMS_LUMINANCE_LEVEL_SET:
  1237. if (ASend) sCmd = "REQ_VMS_LUMINANCE_LEVEL_SET";
  1238. else sCmd = "RES_VMS_LUMINANCE_LEVEL_SET";
  1239. break;
  1240. case REQ_SIGNBOARD_POWER_CONTROL:
  1241. if (ASend) sCmd = "REQ_SIGNBOARD_POWER_CONTROL";
  1242. else sCmd = "RES_SIGNBOARD_POWER_CONTROL";
  1243. break;
  1244. default:
  1245. if (ASend) LERROR("Send Unknown OpCode: %02X, %d Bytes", Pkt->hd.OpCode, ALen);
  1246. else LERROR("Recv Unknown OpCode: %02X, %d Bytes", Pkt->hd.OpCode, ALen);
  1247. return;
  1248. }
  1249. if (ASend)
  1250. {
  1251. if (AResult == SYS_ERR_NONE)
  1252. LINFO("Send: %s, %d Bytes", sCmd.c_str(), ALen);
  1253. else
  1254. LINFO("Send Fail: %s, %d Bytes", sCmd.c_str(), ALen);
  1255. }
  1256. else
  1257. {
  1258. if (acknak)
  1259. {
  1260. res.ack = ABuff[POS_ACKNAK];
  1261. if (res.ack == 0x00)
  1262. LINFO("Recv: %s, %d Bytes", sCmd.c_str(), ALen);
  1263. else
  1264. LINFO("Recv: %s, %d Bytes, NAK(%d,%d,%d,%d,%d)", sCmd.c_str(), ALen,
  1265. res.nak.crc,
  1266. res.nak.cmd,
  1267. res.nak.dat,
  1268. res.nak.nbr,
  1269. res.nak.chk
  1270. );
  1271. }
  1272. else
  1273. {
  1274. LINFO("Recv: %s, %d Bytes", sCmd.c_str(), ALen);
  1275. }
  1276. }
  1277. }
  1278. //---------------------------------------------------------------------------
  1279. void TVMSCThread::ReqStatus()
  1280. {
  1281. try
  1282. {
  1283. FClient.reqStatusTimer = Now() - ITSCOMM_SECTIME(FClient.pollingCycleTime+10);
  1284. }
  1285. catch(Exception &e)
  1286. {
  1287. }
  1288. }
  1289. //---------------------------------------------------------------------------
  1290. int TVMSCThread::LogData(char *ASndRcv, BYTE *AData, int ALen)
  1291. {
  1292. int result = -1;
  1293. int nStep = 0;
  1294. if (!FLogFile) return result;
  1295. if (!FLogFile->FLogCfg.Data) return result;
  1296. try
  1297. {
  1298. FLogFile->LogData(ASndRcv, AData, ALen);
  1299. if (FVmsObj->FDispLog)
  1300. {
  1301. IPC_LOG_MESSAGE *pLog = &FLogMsg;//new IPC_LOG_MESSAGE;
  1302. if (pLog)
  1303. {
  1304. pLog->Kind = eLOG_DATA;
  1305. pLog->Flag = ASndRcv[0] == 'S' ? 1 : 2;
  1306. pLog->Len = ALen > MAX_LOG_BUFFER ? MAX_LOG_BUFFER-1 : ALen;
  1307. pLog->Tm = Now();
  1308. pLog->Type = 'C';
  1309. memset(pLog->Msg, 0x00, sizeof(pLog->Msg));
  1310. memcpy(pLog->Msg, (char*)AData, pLog->Len);
  1311. pLog->Obj = (void*)FVmsObj;
  1312. DWORD dwResult = 0;
  1313. LRESULT lResult = SEND_LOGMSG(FrmVmsLog->Handle, WM_LOG_DISPLAY, (WPARAM)pLog, NULL, SMTO_NORMAL, 2000, dwResult);
  1314. if (lResult == 0)
  1315. {
  1316. dwResult = GetLastError();
  1317. if (dwResult == ERROR_TIMEOUT)
  1318. {
  1319. }
  1320. //SAFE_DELETE(pLog);
  1321. }
  1322. }
  1323. }
  1324. }
  1325. catch(Exception &e)
  1326. {
  1327. }
  1328. return result;
  1329. }
  1330. //---------------------------------------------------------------------------
  1331. int TVMSCThread::SysLogWrite(int ALogKind, char *AFmt, ...)
  1332. {
  1333. va_list ap;
  1334. int cnt = 0;
  1335. char szFmtData[MAX_LOG_BUFFER];
  1336. AnsiString sLogKind;
  1337. int nStep = 0;
  1338. if (!FLogFile) return cnt;
  1339. bool bLog = false;
  1340. switch(ALogKind)
  1341. {
  1342. case eLOG_INFO : bLog = FLogFile->FLogCfg.Info; sLogKind = " [INF] "; break;
  1343. case eLOG_DATA : bLog = FLogFile->FLogCfg.Data; sLogKind = " [DAT] "; break;
  1344. case eLOG_ERROR : bLog = FLogFile->FLogCfg.Error; sLogKind = " [ERR] "; break;
  1345. case eLOG_WARNING: bLog = FLogFile->FLogCfg.Warning; sLogKind = " [WAN] "; break;
  1346. case eLOG_DEBUG : bLog = FLogFile->FLogCfg.Debug; sLogKind = " [DBG] "; break;
  1347. case eLOG_DETAIL : bLog = FLogFile->FLogCfg.Detail; sLogKind = " [DET] "; break;
  1348. }
  1349. if (!bLog) return -1;
  1350. try
  1351. {
  1352. va_start(ap, AFmt);
  1353. cnt = vsprintf(szFmtData, AFmt, ap);
  1354. va_end(ap);
  1355. FLogFile->LogWrite(NULL, ALogKind, szFmtData);
  1356. IPC_LOG_MESSAGE *pLog = &FLogMsg;//new IPC_LOG_MESSAGE;
  1357. if (pLog)
  1358. {
  1359. pLog->Kind = ALogKind;
  1360. pLog->Flag = 0;
  1361. pLog->Len = strlen(szFmtData);
  1362. pLog->Tm = Now();
  1363. pLog->Type = 'C';
  1364. memset(pLog->Msg, 0x00, sizeof(pLog->Msg));
  1365. sprintf(pLog->Msg, "%s-CLI %s, %s", sLogKind.c_str(), VMSID.c_str(), szFmtData);
  1366. pLog->Obj = (void*)FVmsObj;
  1367. DWORD dwResult = 0;
  1368. LRESULT lResult = SEND_LOGMSG(FrmSysLog->Handle, WM_LOG_DISPLAY, pLog, NULL, SMTO_NORMAL, 2000, dwResult);
  1369. if (lResult == 0)
  1370. {
  1371. dwResult = GetLastError();
  1372. if (dwResult == ERROR_TIMEOUT)
  1373. {
  1374. }
  1375. //SAFE_DELETE(pLog);
  1376. }
  1377. }
  1378. if (FVmsObj->FDispLog)
  1379. {
  1380. IPC_LOG_MESSAGE *pLog2 = &FLogMsg;//new IPC_LOG_MESSAGE;
  1381. if (pLog2)
  1382. {
  1383. pLog2->Kind = ALogKind;
  1384. pLog2->Flag = 0;
  1385. pLog2->Len = strlen(szFmtData);
  1386. pLog2->Tm = Now();
  1387. pLog2->Type = 'C';
  1388. memset(pLog2->Msg, 0x00, sizeof(pLog2->Msg));
  1389. sprintf(pLog2->Msg, "%s-CLI %s, %s", sLogKind.c_str(), VMSID.c_str(), szFmtData);
  1390. pLog2->Obj = (void*)FVmsObj;
  1391. DWORD dwResult = 0;
  1392. LRESULT lResult = SEND_LOGMSG(FrmVmsLog->Handle, WM_LOG_DISPLAY, pLog2, NULL, SMTO_NORMAL, 2000, dwResult);
  1393. if (lResult == 0)
  1394. {
  1395. dwResult = GetLastError();
  1396. if (dwResult == ERROR_TIMEOUT)
  1397. {
  1398. }
  1399. //SAFE_DELETE(pLog2);
  1400. }
  1401. }
  1402. }
  1403. }
  1404. catch(Exception &e)
  1405. {
  1406. }
  1407. return cnt;
  1408. }
  1409. //---------------------------------------------------------------------------
  1410. int TVMSCThread::LogWrite(int ALogKind, char *AFmt, ...)
  1411. {
  1412. va_list ap;
  1413. int cnt = 0;
  1414. char szFmtData[MAX_LOG_BUFFER];
  1415. AnsiString sLogKind;
  1416. int nStep = 0;
  1417. if (!FLogFile) return cnt;
  1418. bool bLog = false;
  1419. switch(ALogKind)
  1420. {
  1421. case eLOG_INFO : bLog = FLogFile->FLogCfg.Info; sLogKind = " [INF] "; break;
  1422. case eLOG_DATA : bLog = FLogFile->FLogCfg.Data; sLogKind = " [DAT] "; break;
  1423. case eLOG_ERROR : bLog = FLogFile->FLogCfg.Error; sLogKind = " [ERR] "; break;
  1424. case eLOG_WARNING: bLog = FLogFile->FLogCfg.Warning; sLogKind = " [WAN] "; break;
  1425. case eLOG_DEBUG : bLog = FLogFile->FLogCfg.Debug; sLogKind = " [DBG] "; break;
  1426. case eLOG_DETAIL : bLog = FLogFile->FLogCfg.Detail; sLogKind = " [DET] "; break;
  1427. }
  1428. if (!bLog) return -1;
  1429. try
  1430. {
  1431. va_start(ap, AFmt);
  1432. cnt = vsprintf(szFmtData, AFmt, ap);
  1433. va_end(ap);
  1434. FLogFile->LogWrite(NULL, ALogKind, szFmtData);
  1435. if (FVmsObj->FDispLog)
  1436. {
  1437. IPC_LOG_MESSAGE *pLog = &FLogMsg;//new IPC_LOG_MESSAGE;
  1438. if (pLog)
  1439. {
  1440. pLog->Kind = ALogKind;
  1441. pLog->Flag = 0;
  1442. pLog->Len = strlen(szFmtData);
  1443. pLog->Tm = Now();
  1444. pLog->Type = 'C';
  1445. memset(pLog->Msg, 0x00, sizeof(pLog->Msg));
  1446. sprintf(pLog->Msg, "%s-CLI %s, %s", sLogKind.c_str(), VMSID.c_str(), szFmtData);
  1447. pLog->Obj = (void*)FVmsObj;
  1448. DWORD dwResult = 0;
  1449. LRESULT lResult = SEND_LOGMSG(FrmVmsLog->Handle, WM_LOG_DISPLAY, pLog, NULL, SMTO_NORMAL, 2000, dwResult);
  1450. if (lResult == 0)
  1451. {
  1452. dwResult = GetLastError();
  1453. if (dwResult == ERROR_TIMEOUT)
  1454. {
  1455. }
  1456. //SAFE_DELETE(pLog);
  1457. }
  1458. }
  1459. }
  1460. }
  1461. catch(Exception &e)
  1462. {
  1463. }
  1464. return cnt;
  1465. }
  1466. //---------------------------------------------------------------------------