123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- //---------------------------------------------------------------------------
- #pragma hdrstop
- #include "VMSCThread.h"
- #include "VMSCThreadSendF.h"
- //---------------------------------------------------------------------------
- #pragma package(smart_init)
- /*
- * 송신 패킷 처리
- * arguments
- * void
- * return
- * void
- */
- int __fastcall TVMSCThread::ProcessSendPacket(BYTE AOpCode, COMMAND_ARGUMENT *AArg)
- {
- FErrLine = 10;
- VMS_PACKET *Pkt = (VMS_PACKET*)m_TxBuff;
- int result = SYS_ERR_NONE;
- int nData = 0;
- int sndLen = 0;
- unsigned crc;
- unsigned short year, mon, day;
- unsigned short hour, min, sec, msec;
- Now().DecodeDate(&year, &mon, &day);
- Now().DecodeTime(&hour, &min, &sec, &msec);
- Pkt->hd.STX = VMS_STX; // STX, 0x02
- Pkt->hd.ID = 0x00; // Reserved, 0x00
- Pkt->hd.OpCode = AOpCode; // OpCode
- sprintf(Pkt->hd.ADDR, "%04d", FVmsObj->Id); // Address
- switch(AOpCode)
- {
- case REQ_VMS_STATUS:// 0x50 // Status 요청, 센터->VMS
- Pkt->data[nData++] = (BYTE)HIBYTE(year);
- Pkt->data[nData++] = (BYTE)LOBYTE(year);
- Pkt->data[nData++] = (BYTE)mon;
- Pkt->data[nData++] = (BYTE)day;
- Pkt->data[nData++] = (BYTE)hour;
- Pkt->data[nData++] = (BYTE)min;
- Pkt->data[nData++] = (BYTE)sec;
- break;
- case REQ_VMS_MSG_DOWNLOAD:// 0x51 // 문안 전송 요청, 센터->VMS
- nData = MakeMsgDownload(Pkt->data, AArg);
- if (nData <= 0)
- {
- LERROR(">>> MakeMsgDownload Faild");
- return SYS_ERR_DATABASE;
- }
- break;
- case REQ_VMS_LIB_DOWNLOAD:// 0x52 // Library download 요청, 센터->VMS
- nData = MakeLibDownload(Pkt->data, AArg);
- if (nData <= 0)
- {
- LERROR(">>> MakeLibDownload Faild");
- return SYS_ERR_DATABASE;
- }
- break;
- case REQ_VMS_PARAM_DOWNLOAD:// 0x53 // Parameter download 요청, 센터->VMS
- Pkt->data[nData++] = AArg->Publication.Data.Set2.DefCommErr; // 통신장애 기본값, 제어기가 Host로부터 Poll 또는 명령을 받지 않고 경과할 수 있는 최대시간 (default ; 60초)
- Pkt->data[nData++] = (BYTE)HIBYTE(AArg->Publication.Data.Set2.SlotCommErr); // 통신장애 slot번호, 통신 fail 시 표시할 메시지 번호(default 0번)
- Pkt->data[nData++] = (BYTE)LOBYTE(AArg->Publication.Data.Set2.SlotCommErr); // 통신장애 slot번호, 통신 fail 시 표시할 메시지 번호(default 0번)
- Pkt->data[nData++] = (BYTE)HIBYTE(AArg->Publication.Data.Set2.SlotPowerErr); // 전원장애 slot번호, 전원장애 시 표시할 메시지 번호(default 0번)
- Pkt->data[nData++] = (BYTE)LOBYTE(AArg->Publication.Data.Set2.SlotPowerErr); // 전원장애 slot번호, 전원장애 시 표시할 메시지 번호(default 0번)
- Pkt->data[nData++] = AArg->Publication.Data.Set2.NightLuminance; // 야간 휘도 값, 0x30 ~ 0x3F
- Pkt->data[nData++] = AArg->Publication.Data.Set2.DayLuminance; // 주간 휘도 값, 0x40 ~ 0x4F
- Pkt->data[nData++] = AArg->Publication.Data.Set2.PhaseCycleTime; // phase시간주기, 장애시 phase주기 (default : 3초, 범위 : 0 ~ 10초)
- Pkt->data[nData++] = AArg->Publication.Data.Set2.ModuleFailRate; // 모듈장애율, 한개의 module을 장애로 처리하기 위한 장애 pixel백분율 (default 10%)
- Pkt->data[nData++] = AArg->Publication.Data.Set2.ModuleCheckTime; // 모듈감시 주기, 0 ~ 255 (단위:초)
- Pkt->data[nData++] = AArg->Publication.Data.Set2.BoardOnHour; // 전광판 On time(시), 0시 ~ 23시
- Pkt->data[nData++] = AArg->Publication.Data.Set2.BoardOnMin; // 전광판 On time(분), 0시 ~ 23시
- Pkt->data[nData++] = AArg->Publication.Data.Set2.BoardOffHour; // 전광판 Off time(시), 0시 ~ 23시
- Pkt->data[nData++] = AArg->Publication.Data.Set2.BoardOffMin; // 전광판 Off time(분), 0시 ~ 23시
- #if 0
- 11 통신장애 기본값 제어기가 Host로부터 Poll 또는 명령을 받지 않고 경과할 수 있는 최대시간 (default ; 60초)
- 12 통신장애 slot번호 통신 fail 시 표시할 메시지 번호(default 0번)
- 13
- 14 전원장애 slot번호 전원장애 시 표시할 메시지 번호(default 0번)
- 15
- 16 야간 휘도 값 0x30 ~ 0x3F
- 17 주간 휘도 값 0x40 ~ 0x4F
- 18 phase시간주기 장애시 phase주기 (default : 3초, 범위 : 0 ~ 10초)
- 19 모듈장애율 한개의 module을 장애로 처리하기 위한 장애 pixel백분율 (default 10%)
- 20 모듈감시 주기 0 ~ 255 (단위:초)
- 21 전광판 On time(시) 0시 ~ 23시 0x00000000 : 없음
- 22 전광판 On time(분) 0분 ~ 59분
- 23 전광판 Off time(시) 0시 ~ 23시
- 24 전광판 Off time(분) 0분 ~ 59분
- #endif
- break;
- case REQ_VMS_BLANK_DISP:// 0x54 // Blank 요청, 센터->VMS
- //설정데이터없이 헤더로 정보로 전송
- break;
- case REQ_VMS_DEF_MSG_DISP:// 0x55 // Default message display 요청, 센터->VMS
- //설정데이터없이 헤더로 정보로 전송
- break;
- case REQ_VMS_MODULE_STATUS:// 0x56 // Module status upload 요청, 센터->VMS
- //설정데이터없이 헤더로 정보로 전송
- break;
- case REQ_VMS_INITIALIZE:// 0x57 // Initialize 요청, 센터->VMS
- //설정데이터없이 헤더로 정보로 전송
- break;
- case REQ_VMS_LUMINANCE_LEVEL_SET:// 0x58 // Luminance level set 요청, 센터->VMS
- Pkt->data[nData++] = AArg->Publication.Data.Ctl;
- break;
- case REQ_SIGNBOARD_POWER_CONTROL:// 0x59 // Signboard power control 요청, 센터->VMS
- Pkt->data[nData++] = AArg->Publication.Data.Ctl;
- break;
- default:
- LERROR(">>> Unknown ProcessSendPacket: 0x%02X", AOpCode);
- return SYS_ERR_UNKNOWN_COMMAND;
- }
- #if 0
- BYTE STX;
- BYTE ID;
- BYTE OpCode;
- UINT Size;
- char ADDR[4];
- char DATA[n];
- char CRC[2];
- char ETX;
- #endif
- sndLen = nData+1+1+4+4+2; // ID부터 CRC까지의 전체 길이(byte order준수)
- Pkt->hd.Size = CommUtil_swapl((DWORD)sndLen);
- crc = CommUtil_MakeCrc16((void*)&Pkt->hd.ID, (WORD)(sndLen-2)); //ID부터 DATA까지의 CRC-16 생성다항식에 의해 계산된 값
- Pkt->data[nData++] = HIBYTE(crc); // CRC
- Pkt->data[nData++] = LOBYTE(crc); // CRC
- Pkt->data[nData++] = VMS_ETX; // ETX, 0x03
- result = SendPacket((BYTE*)Pkt, sndLen+2); //STX+Pkt->Size+ETX
- return result;
- }
- //---------------------------------------------------------------------------
- int __fastcall TVMSCThread::MakeMsgDownload(BYTE *ABuff, COMMAND_ARGUMENT *AArg)
- {
- int nData = 0;
- int nForms = 0;
- unsigned int nImgSize;
- TVmsForm *pVmsForm = NULL;
- AnsiString MessageId;
- int ii;
- bool bException = false;
- try
- {
- m_pVmsFormList->Lock();
- int nFormCnt = m_pVmsFormList->Count();
- if (nFormCnt > 9) nFormCnt = 9;
- if (nFormCnt <= 0)
- {
- SERROR("Msg Download Form Count is zero ! ! !");
- return -1;
- }
- ABuff[nData++] = 0x07; // 정지화면 (Stationary)
- ABuff[nData++] = 0x02; // Left(오른쪽에서 왼쪽으로)
- int nDispTime = FVmsObj->VMS_PHSE_CHNG_CYCL;
- if (FVmsObj->VMS_PHSE_CHNG_CYCL < 3) nDispTime = 3;
- if (FVmsObj->VMS_PHSE_CHNG_CYCL > 10) nDispTime = 10;
- ABuff[nData++] = (BYTE)nDispTime;//0x05; // 표출 시간/기간
- ABuff[nData++] = (BYTE)nFormCnt-1; // PHASE 갯수(0x00-1EA, 0x01 ~ 0x08=9EA)
- LDEBUG("Display Time: %d sec, Forms: %d", nDispTime, nFormCnt);
- for (int ii = 0; ii < nFormCnt; ii++)
- {
- pVmsForm = m_pVmsFormList->GetItem(ii);
- if (!pVmsForm)
- {
- SERROR("Msg FormId Memory Not Found: %d", ii);
- continue;
- }
- #if 0
- LINFO(" pVmsForm->DisplayTime: %d", pVmsForm->DisplayTime);
- LINFO("pVmsForm->DisplayMode.ToIntDef(0): %d", pVmsForm->DisplayMode.ToIntDef(0));
- LINFO(" pVmsForm->DisplayDir.ToIntDef(0): %d", pVmsForm->DisplayDir.ToIntDef(0));
- LINFO(" pVmsForm->pStream->Size: %d", pVmsForm->pStream->Size);
- #endif
- nImgSize = pVmsForm->pStream->Size;
- ABuff[nData++] = 'G'; //G: 그래픽, T: Text, B: Bar, S: Symbol
- ABuff[nData++] = (BYTE)(nImgSize >> 24) & 0xFFFFFFFF;
- ABuff[nData++] = (BYTE)(nImgSize >> 16) & 0xFFFFFFFF;
- ABuff[nData++] = (BYTE)(nImgSize >> 8) & 0xFFFFFFFF;
- ABuff[nData++] = (BYTE)(nImgSize ) & 0xFFFFFFFF;
- try
- {
- pVmsForm->pStream->Position = 0;
- memcpy((char*)&ABuff[nData], (char *)pVmsForm->pStream->Memory, nImgSize);
- nData += nImgSize;
- }
- catch(Exception &e)
- {
- bException = true;
- SERROR("MemoryStream Allocation error: %s, FormId: %s", AnsiString(e.Message).c_str(), pVmsForm->FormId.c_str());
- }
- }
- }
- __finally
- {
- m_pVmsFormList->UnLock();
- }
- return nData;
- }
- //---------------------------------------------------------------------------
- int __fastcall TVMSCThread::MakeLibDownload(BYTE *ABuff, COMMAND_ARGUMENT *AArg)
- {
- int nData = 0;
- int nForms = 0;
- unsigned int nImgSize;
- TVmsForm *pVmsForm = NULL;
- AnsiString MessageId;
- int ii;
- bool bException = false;
- try
- {
- m_pVmsFormList->Lock();
- int nFormCnt = m_pVmsFormList->Count();
- if (nFormCnt > 9) nFormCnt = 9;
- if (nFormCnt <= 0)
- {
- SERROR("Msg Download Form Count is zero ! ! !");
- return -1;
- }
- #if 0
- □ LIBRARY 메시지 번호의 범위
- - Text Message Number : 1000 - 5999
- - Graphic Symbol Message Number : 6000 - 8999
- - Full Graphic Message Number : 9000 - 9999
- - Message Number 0 은 Default Message
- #endif
- int nLibNo = 0;
- ABuff[nData++] = 0x07; // 정지화면 (Stationary)
- ABuff[nData++] = 0x02; // Left(오른쪽에서 왼쪽으로)
- ABuff[nData++] = (BYTE)(nLibNo >> 8) & 0xFFFFFFFF;
- ABuff[nData++] = (BYTE)(nLibNo ) & 0xFFFFFFFF;
- ABuff[nData++] = (BYTE)nFormCnt; // PHASE 갯수(0x00-1EA, 0x01 ~ 0x08=9EA)
- LDEBUG("Lib Download: Forms: %d", nFormCnt);
- for (int ii = 0; ii < nFormCnt; ii++)
- {
- pVmsForm = m_pVmsFormList->GetItem(ii);
- if (!pVmsForm)
- {
- SERROR("Msg FormId Memory Not Found: %d", ii);
- continue;
- }
- #if 0
- LINFO(" pVmsForm->DisplayTime: %d", pVmsForm->DisplayTime);
- LINFO("pVmsForm->DisplayMode.ToIntDef(0): %d", pVmsForm->DisplayMode.ToIntDef(0));
- LINFO(" pVmsForm->DisplayDir.ToIntDef(0): %d", pVmsForm->DisplayDir.ToIntDef(0));
- LINFO(" pVmsForm->pStream->Size: %d", pVmsForm->pStream->Size);
- #endif
- nImgSize = pVmsForm->pStream->Size;
- ABuff[nData++] = 'S'; //G: 그래픽, T: Text, B: Bar, S: Symbol
- ABuff[nData++] = (BYTE)(nImgSize >> 24) & 0xFFFFFFFF;
- ABuff[nData++] = (BYTE)(nImgSize >> 16) & 0xFFFFFFFF;
- ABuff[nData++] = (BYTE)(nImgSize >> 8) & 0xFFFFFFFF;
- ABuff[nData++] = (BYTE)(nImgSize ) & 0xFFFFFFFF;
- try
- {
- pVmsForm->pStream->Position = 0;
- memcpy((char*)&ABuff[nData], (char *)pVmsForm->pStream->Memory, nImgSize);
- nData += nImgSize;
- }
- catch(Exception &e)
- {
- bException = true;
- SERROR("MemoryStream Allocation error: %s, FormId: %s", AnsiString(e.Message).c_str(), pVmsForm->FormId.c_str());
- }
- }
- }
- __finally
- {
- m_pVmsFormList->UnLock();
- }
- return nData;
- }
- //---------------------------------------------------------------------------
- /*
- * 패킷 송신
- * arguments
- * void
- * return
- * void
- */
- int __fastcall TVMSCThread::SendPacket(BYTE *ACmdBuff, int AReqSendLen)
- {
- int result = SYS_ERR_NONE;
- try
- {
- int nSendBytes = TcpClient->SendBuf(ACmdBuff, AReqSendLen);
- if (nSendBytes == AReqSendLen)
- {
- FClient.sendRetry--;
- FClient.sendTimer = Now();
- }
- else
- {
- result = SYS_ERR_WRITE_LENGTH;
- }
- if (SYS_ERR_NONE == result) LogData("SEND", ACmdBuff, AReqSendLen);
- else LogData("SEND Fail", ACmdBuff, nSendBytes);
- InfoPacket(ACmdBuff, nSendBytes, true, result);
- }
- catch(Exception &e)
- {
- result = SYS_ERR_MEMORY;
- }
- return result;
- }
- //---------------------------------------------------------------------------
|