VMSCThreadSendF.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. //---------------------------------------------------------------------------
  2. #pragma hdrstop
  3. #include "VMSCThread.h"
  4. #include "VMSCThreadSendF.h"
  5. //---------------------------------------------------------------------------
  6. #pragma package(smart_init)
  7. /*
  8. * 송신 패킷 처리
  9. * arguments
  10. * void
  11. * return
  12. * void
  13. */
  14. int __fastcall TVMSCThread::ProcessSendPacket(BYTE AOpCode, COMMAND_ARGUMENT *AArg)
  15. {
  16. FErrLine = 10;
  17. VMS_PACKET *Pkt = (VMS_PACKET*)m_TxBuff;
  18. int result = SYS_ERR_NONE;
  19. int nData = 0;
  20. int sndLen = 0;
  21. unsigned crc;
  22. unsigned short year, mon, day;
  23. unsigned short hour, min, sec, msec;
  24. Now().DecodeDate(&year, &mon, &day);
  25. Now().DecodeTime(&hour, &min, &sec, &msec);
  26. Pkt->hd.STX = VMS_STX; // STX, 0x02
  27. Pkt->hd.ID = 0x00; // Reserved, 0x00
  28. Pkt->hd.OpCode = AOpCode; // OpCode
  29. sprintf(Pkt->hd.ADDR, "%04d", FVmsObj->Id); // Address
  30. switch(AOpCode)
  31. {
  32. case REQ_VMS_STATUS:// 0x50 // Status 요청, 센터->VMS
  33. Pkt->data[nData++] = (BYTE)HIBYTE(year);
  34. Pkt->data[nData++] = (BYTE)LOBYTE(year);
  35. Pkt->data[nData++] = (BYTE)mon;
  36. Pkt->data[nData++] = (BYTE)day;
  37. Pkt->data[nData++] = (BYTE)hour;
  38. Pkt->data[nData++] = (BYTE)min;
  39. Pkt->data[nData++] = (BYTE)sec;
  40. break;
  41. case REQ_VMS_MSG_DOWNLOAD:// 0x51 // 문안 전송 요청, 센터->VMS
  42. nData = MakeMsgDownload(Pkt->data, AArg);
  43. if (nData <= 0)
  44. {
  45. LERROR(">>> MakeMsgDownload Faild");
  46. return SYS_ERR_DATABASE;
  47. }
  48. break;
  49. case REQ_VMS_LIB_DOWNLOAD:// 0x52 // Library download 요청, 센터->VMS
  50. nData = MakeLibDownload(Pkt->data, AArg);
  51. if (nData <= 0)
  52. {
  53. LERROR(">>> MakeLibDownload Faild");
  54. return SYS_ERR_DATABASE;
  55. }
  56. break;
  57. case REQ_VMS_PARAM_DOWNLOAD:// 0x53 // Parameter download 요청, 센터->VMS
  58. Pkt->data[nData++] = AArg->Publication.Data.Set2.DefCommErr; // 통신장애 기본값, 제어기가 Host로부터 Poll 또는 명령을 받지 않고 경과할 수 있는 최대시간 (default ; 60초)
  59. Pkt->data[nData++] = (BYTE)HIBYTE(AArg->Publication.Data.Set2.SlotCommErr); // 통신장애 slot번호, 통신 fail 시 표시할 메시지 번호(default 0번)
  60. Pkt->data[nData++] = (BYTE)LOBYTE(AArg->Publication.Data.Set2.SlotCommErr); // 통신장애 slot번호, 통신 fail 시 표시할 메시지 번호(default 0번)
  61. Pkt->data[nData++] = (BYTE)HIBYTE(AArg->Publication.Data.Set2.SlotPowerErr); // 전원장애 slot번호, 전원장애 시 표시할 메시지 번호(default 0번)
  62. Pkt->data[nData++] = (BYTE)LOBYTE(AArg->Publication.Data.Set2.SlotPowerErr); // 전원장애 slot번호, 전원장애 시 표시할 메시지 번호(default 0번)
  63. Pkt->data[nData++] = AArg->Publication.Data.Set2.NightLuminance; // 야간 휘도 값, 0x30 ~ 0x3F
  64. Pkt->data[nData++] = AArg->Publication.Data.Set2.DayLuminance; // 주간 휘도 값, 0x40 ~ 0x4F
  65. Pkt->data[nData++] = AArg->Publication.Data.Set2.PhaseCycleTime; // phase시간주기, 장애시 phase주기 (default : 3초, 범위 : 0 ~ 10초)
  66. Pkt->data[nData++] = AArg->Publication.Data.Set2.ModuleFailRate; // 모듈장애율, 한개의 module을 장애로 처리하기 위한 장애 pixel백분율 (default 10%)
  67. Pkt->data[nData++] = AArg->Publication.Data.Set2.ModuleCheckTime; // 모듈감시 주기, 0 ~ 255 (단위:초)
  68. Pkt->data[nData++] = AArg->Publication.Data.Set2.BoardOnHour; // 전광판 On time(시), 0시 ~ 23시
  69. Pkt->data[nData++] = AArg->Publication.Data.Set2.BoardOnMin; // 전광판 On time(분), 0시 ~ 23시
  70. Pkt->data[nData++] = AArg->Publication.Data.Set2.BoardOffHour; // 전광판 Off time(시), 0시 ~ 23시
  71. Pkt->data[nData++] = AArg->Publication.Data.Set2.BoardOffMin; // 전광판 Off time(분), 0시 ~ 23시
  72. #if 0
  73. 11 통신장애 기본값 제어기가 Host로부터 Poll 또는 명령을 받지 않고 경과할 수 있는 최대시간 (default ; 60초)
  74. 12 통신장애 slot번호 통신 fail 시 표시할 메시지 번호(default 0번)
  75. 13
  76. 14 전원장애 slot번호 전원장애 시 표시할 메시지 번호(default 0번)
  77. 15
  78. 16 야간 휘도 값 0x30 ~ 0x3F
  79. 17 주간 휘도 값 0x40 ~ 0x4F
  80. 18 phase시간주기 장애시 phase주기 (default : 3초, 범위 : 0 ~ 10초)
  81. 19 모듈장애율 한개의 module을 장애로 처리하기 위한 장애 pixel백분율 (default 10%)
  82. 20 모듈감시 주기 0 ~ 255 (단위:초)
  83. 21 전광판 On time(시) 0시 ~ 23시 0x00000000 : 없음
  84. 22 전광판 On time(분) 0분 ~ 59분
  85. 23 전광판 Off time(시) 0시 ~ 23시
  86. 24 전광판 Off time(분) 0분 ~ 59분
  87. #endif
  88. break;
  89. case REQ_VMS_BLANK_DISP:// 0x54 // Blank 요청, 센터->VMS
  90. //설정데이터없이 헤더로 정보로 전송
  91. break;
  92. case REQ_VMS_DEF_MSG_DISP:// 0x55 // Default message display 요청, 센터->VMS
  93. //설정데이터없이 헤더로 정보로 전송
  94. break;
  95. case REQ_VMS_MODULE_STATUS:// 0x56 // Module status upload 요청, 센터->VMS
  96. //설정데이터없이 헤더로 정보로 전송
  97. break;
  98. case REQ_VMS_INITIALIZE:// 0x57 // Initialize 요청, 센터->VMS
  99. //설정데이터없이 헤더로 정보로 전송
  100. break;
  101. case REQ_VMS_LUMINANCE_LEVEL_SET:// 0x58 // Luminance level set 요청, 센터->VMS
  102. Pkt->data[nData++] = AArg->Publication.Data.Ctl;
  103. break;
  104. case REQ_SIGNBOARD_POWER_CONTROL:// 0x59 // Signboard power control 요청, 센터->VMS
  105. Pkt->data[nData++] = AArg->Publication.Data.Ctl;
  106. break;
  107. default:
  108. LERROR(">>> Unknown ProcessSendPacket: 0x%02X", AOpCode);
  109. return SYS_ERR_UNKNOWN_COMMAND;
  110. }
  111. #if 0
  112. BYTE STX;
  113. BYTE ID;
  114. BYTE OpCode;
  115. UINT Size;
  116. char ADDR[4];
  117. char DATA[n];
  118. char CRC[2];
  119. char ETX;
  120. #endif
  121. sndLen = nData+1+1+4+4+2; // ID부터 CRC까지의 전체 길이(byte order준수)
  122. Pkt->hd.Size = CommUtil_swapl((DWORD)sndLen);
  123. crc = CommUtil_MakeCrc16((void*)&Pkt->hd.ID, (WORD)(sndLen-2)); //ID부터 DATA까지의 CRC-16 생성다항식에 의해 계산된 값
  124. Pkt->data[nData++] = HIBYTE(crc); // CRC
  125. Pkt->data[nData++] = LOBYTE(crc); // CRC
  126. Pkt->data[nData++] = VMS_ETX; // ETX, 0x03
  127. result = SendPacket((BYTE*)Pkt, sndLen+2); //STX+Pkt->Size+ETX
  128. return result;
  129. }
  130. //---------------------------------------------------------------------------
  131. int __fastcall TVMSCThread::MakeMsgDownload(BYTE *ABuff, COMMAND_ARGUMENT *AArg)
  132. {
  133. int nData = 0;
  134. int nForms = 0;
  135. unsigned int nImgSize;
  136. TVmsForm *pVmsForm = NULL;
  137. AnsiString MessageId;
  138. int ii;
  139. bool bException = false;
  140. try
  141. {
  142. m_pVmsFormList->Lock();
  143. int nFormCnt = m_pVmsFormList->Count();
  144. if (nFormCnt > 9) nFormCnt = 9;
  145. if (nFormCnt <= 0)
  146. {
  147. SERROR("Msg Download Form Count is zero ! ! !");
  148. return -1;
  149. }
  150. ABuff[nData++] = 0x07; // 정지화면 (Stationary)
  151. ABuff[nData++] = 0x02; // Left(오른쪽에서 왼쪽으로)
  152. int nDispTime = FVmsObj->VMS_PHSE_CHNG_CYCL;
  153. if (FVmsObj->VMS_PHSE_CHNG_CYCL < 3) nDispTime = 3;
  154. if (FVmsObj->VMS_PHSE_CHNG_CYCL > 10) nDispTime = 10;
  155. ABuff[nData++] = (BYTE)nDispTime;//0x05; // 표출 시간/기간
  156. ABuff[nData++] = (BYTE)nFormCnt-1; // PHASE 갯수(0x00-1EA, 0x01 ~ 0x08=9EA)
  157. LDEBUG("Display Time: %d sec, Forms: %d", nDispTime, nFormCnt);
  158. for (int ii = 0; ii < nFormCnt; ii++)
  159. {
  160. pVmsForm = m_pVmsFormList->GetItem(ii);
  161. if (!pVmsForm)
  162. {
  163. SERROR("Msg FormId Memory Not Found: %d", ii);
  164. continue;
  165. }
  166. #if 0
  167. LINFO(" pVmsForm->DisplayTime: %d", pVmsForm->DisplayTime);
  168. LINFO("pVmsForm->DisplayMode.ToIntDef(0): %d", pVmsForm->DisplayMode.ToIntDef(0));
  169. LINFO(" pVmsForm->DisplayDir.ToIntDef(0): %d", pVmsForm->DisplayDir.ToIntDef(0));
  170. LINFO(" pVmsForm->pStream->Size: %d", pVmsForm->pStream->Size);
  171. #endif
  172. nImgSize = pVmsForm->pStream->Size;
  173. ABuff[nData++] = 'G'; //G: 그래픽, T: Text, B: Bar, S: Symbol
  174. ABuff[nData++] = (BYTE)(nImgSize >> 24) & 0xFFFFFFFF;
  175. ABuff[nData++] = (BYTE)(nImgSize >> 16) & 0xFFFFFFFF;
  176. ABuff[nData++] = (BYTE)(nImgSize >> 8) & 0xFFFFFFFF;
  177. ABuff[nData++] = (BYTE)(nImgSize ) & 0xFFFFFFFF;
  178. try
  179. {
  180. pVmsForm->pStream->Position = 0;
  181. memcpy((char*)&ABuff[nData], (char *)pVmsForm->pStream->Memory, nImgSize);
  182. nData += nImgSize;
  183. }
  184. catch(Exception &e)
  185. {
  186. bException = true;
  187. SERROR("MemoryStream Allocation error: %s, FormId: %s", AnsiString(e.Message).c_str(), pVmsForm->FormId.c_str());
  188. }
  189. }
  190. }
  191. __finally
  192. {
  193. m_pVmsFormList->UnLock();
  194. }
  195. return nData;
  196. }
  197. //---------------------------------------------------------------------------
  198. int __fastcall TVMSCThread::MakeLibDownload(BYTE *ABuff, COMMAND_ARGUMENT *AArg)
  199. {
  200. int nData = 0;
  201. int nForms = 0;
  202. unsigned int nImgSize;
  203. TVmsForm *pVmsForm = NULL;
  204. AnsiString MessageId;
  205. int ii;
  206. bool bException = false;
  207. try
  208. {
  209. m_pVmsFormList->Lock();
  210. int nFormCnt = m_pVmsFormList->Count();
  211. if (nFormCnt > 9) nFormCnt = 9;
  212. if (nFormCnt <= 0)
  213. {
  214. SERROR("Msg Download Form Count is zero ! ! !");
  215. return -1;
  216. }
  217. #if 0
  218. □ LIBRARY 메시지 번호의 범위
  219. - Text Message Number : 1000 - 5999
  220. - Graphic Symbol Message Number : 6000 - 8999
  221. - Full Graphic Message Number : 9000 - 9999
  222. - Message Number 0 은 Default Message
  223. #endif
  224. int nLibNo = 0;
  225. ABuff[nData++] = 0x07; // 정지화면 (Stationary)
  226. ABuff[nData++] = 0x02; // Left(오른쪽에서 왼쪽으로)
  227. ABuff[nData++] = (BYTE)(nLibNo >> 8) & 0xFFFFFFFF;
  228. ABuff[nData++] = (BYTE)(nLibNo ) & 0xFFFFFFFF;
  229. ABuff[nData++] = (BYTE)nFormCnt; // PHASE 갯수(0x00-1EA, 0x01 ~ 0x08=9EA)
  230. LDEBUG("Lib Download: Forms: %d", nFormCnt);
  231. for (int ii = 0; ii < nFormCnt; ii++)
  232. {
  233. pVmsForm = m_pVmsFormList->GetItem(ii);
  234. if (!pVmsForm)
  235. {
  236. SERROR("Msg FormId Memory Not Found: %d", ii);
  237. continue;
  238. }
  239. #if 0
  240. LINFO(" pVmsForm->DisplayTime: %d", pVmsForm->DisplayTime);
  241. LINFO("pVmsForm->DisplayMode.ToIntDef(0): %d", pVmsForm->DisplayMode.ToIntDef(0));
  242. LINFO(" pVmsForm->DisplayDir.ToIntDef(0): %d", pVmsForm->DisplayDir.ToIntDef(0));
  243. LINFO(" pVmsForm->pStream->Size: %d", pVmsForm->pStream->Size);
  244. #endif
  245. nImgSize = pVmsForm->pStream->Size;
  246. ABuff[nData++] = 'S'; //G: 그래픽, T: Text, B: Bar, S: Symbol
  247. ABuff[nData++] = (BYTE)(nImgSize >> 24) & 0xFFFFFFFF;
  248. ABuff[nData++] = (BYTE)(nImgSize >> 16) & 0xFFFFFFFF;
  249. ABuff[nData++] = (BYTE)(nImgSize >> 8) & 0xFFFFFFFF;
  250. ABuff[nData++] = (BYTE)(nImgSize ) & 0xFFFFFFFF;
  251. try
  252. {
  253. pVmsForm->pStream->Position = 0;
  254. memcpy((char*)&ABuff[nData], (char *)pVmsForm->pStream->Memory, nImgSize);
  255. nData += nImgSize;
  256. }
  257. catch(Exception &e)
  258. {
  259. bException = true;
  260. SERROR("MemoryStream Allocation error: %s, FormId: %s", AnsiString(e.Message).c_str(), pVmsForm->FormId.c_str());
  261. }
  262. }
  263. }
  264. __finally
  265. {
  266. m_pVmsFormList->UnLock();
  267. }
  268. return nData;
  269. }
  270. //---------------------------------------------------------------------------
  271. /*
  272. * 패킷 송신
  273. * arguments
  274. * void
  275. * return
  276. * void
  277. */
  278. int __fastcall TVMSCThread::SendPacket(BYTE *ACmdBuff, int AReqSendLen)
  279. {
  280. int result = SYS_ERR_NONE;
  281. try
  282. {
  283. int nSendBytes = TcpClient->SendBuf(ACmdBuff, AReqSendLen);
  284. if (nSendBytes == AReqSendLen)
  285. {
  286. FClient.sendRetry--;
  287. FClient.sendTimer = Now();
  288. }
  289. else
  290. {
  291. result = SYS_ERR_WRITE_LENGTH;
  292. }
  293. if (SYS_ERR_NONE == result) LogData("SEND", ACmdBuff, AReqSendLen);
  294. else LogData("SEND Fail", ACmdBuff, nSendBytes);
  295. InfoPacket(ACmdBuff, nSendBytes, true, result);
  296. }
  297. catch(Exception &e)
  298. {
  299. result = SYS_ERR_MEMORY;
  300. }
  301. return result;
  302. }
  303. //---------------------------------------------------------------------------