package com.its.op.xnetudp.thread; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.its.op.dto.its.common.NotifyDto; import com.its.op.global.TbIfscManager; import com.its.op.global.TbLinkManager; import com.its.op.global.TbRoadManager; import com.its.op.websocket.ItsWebSocketMessage; import com.its.op.websocket.ItsWebSocketSessionManager; import com.its.op.xnetudp.protocol.CENTER_COMM_DEFINE; import com.its.op.xnetudp.protocol.CENTER_COMM_MESSAGE; import com.its.utils.ItsUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.web.socket.TextMessage; import javax.annotation.PostConstruct; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; @Slf4j @RequiredArgsConstructor @Service public class CenterCommServerReceiver { private final ItsWebSocketSessionManager itsWebSocketSessionManager; private final TbLinkManager linkManager; private final TbIfscManager ifscManager; private final TbRoadManager roadManager; private ObjectMapper mapper; @PostConstruct private void init() { this.mapper = new ObjectMapper(); } @Async("centerCommExecutor") public void run(CENTER_COMM_MESSAGE data) { if (data == null) { log.error("@@@ UDP Data Receive: CenterCommServerReceiver: RECV Data Packet NULL"); return; } log.info("@@@ -UDP Data Receive: CenterCommServerReceiver: Sender[{}], OpCode[{}], SenderIp[{}]", String.format("0x%02X", data.getSendId()), String.format("0x%02X", data.getOpCode()), data.getSenderIp()); if (CENTER_COMM_DEFINE.INT_ID_TRAFFIC_SERVER == data.getSendId()) { if (CENTER_COMM_DEFINE.INT_OP_TRAFFIC_CHANGE == data.getOpCode()) { String prcsTm = ItsUtils.getCurrFiveMinString(); String currTm = ItsUtils.getCurrFiveMinString(); if (data.getLength() >= CENTER_COMM_DEFINE.INT_TRAFFIC_TIME_SIZE) { ByteBuffer byteBuffer = ByteBuffer.wrap(data.getBody()); byteBuffer.order(ByteOrder.LITTLE_ENDIAN); byte[] recvTm = new byte[CENTER_COMM_DEFINE.INT_TRAFFIC_TIME_SIZE]; byteBuffer.get(recvTm); //prcsTm = new String(recvTm); prcsTm = new String(recvTm, StandardCharsets.UTF_8); if (data.getLength() >= (CENTER_COMM_DEFINE.INT_TRAFFIC_TIME_SIZE+CENTER_COMM_DEFINE.INT_TRAFFIC_TIME_SIZE)) { byteBuffer.get(recvTm); //currTm = new String(recvTm); currTm = new String(recvTm, StandardCharsets.UTF_8); } } log.info("@@@ RECV TRF Server Message: Processing Completed, {}/{}", prcsTm, currTm); // 소통정보 메모리 로딩 this.linkManager.loadTraf(true); this.ifscManager.loadTraf(true); this.roadManager.loadTraf(true); NotifyDto notifyDto = NotifyDto.builder() .notify("traffic") .notifyTm(currTm) .notifyCount(0) .notifyMsg(prcsTm) .build(); ItsWebSocketMessage socketMessage = new ItsWebSocketMessage("traffic", notifyDto); try { String jsonData = this.mapper.writeValueAsString(socketMessage); this.itsWebSocketSessionManager.sendBroadcastMessage(socketMessage.getCommand(), new TextMessage(jsonData)); } catch(JsonProcessingException e){ log.error("@@@ RECV TRF Server Message: Processing Completed, Exception: {}", notifyDto); } } return; } // VMS 통신 서버는 Sender, Receiver 위치가 바뀌었음. ==> 서버 수정했음. //if (CENTER_COMM_DEFINE.INT_ID_VMS_OPER == data.getSendId() && CENTER_COMM_DEFINE.INT_ID_VMS_SERVER == data.getRecvId()) { if (CENTER_COMM_DEFINE.INT_ID_VMS_SERVER == data.getSendId()) { //log.info("@@@ RECV VMS Server Message: OpCode: {}, Length: {} Bytes.", data.getOpCode(), data.getLength()); //log.error("VMS PACKET: {}", SysUtils.byteArrayToHex(data.getBody())); if (data.getLength() > 0) { ByteBuffer byteBuffer = ByteBuffer.wrap(data.getBody()); byteBuffer.order(ByteOrder.LITTLE_ENDIAN); byte[] vmsId; byte count; byte opCode = data.getOpCode(); //byte msgSeq = data.getMsgSeq(); //log.info("OP CODE: {}, MsgSeq: {}", opCode, msgSeq); switch(opCode) { case CENTER_COMM_DEFINE.INT_OP_PG_STATE_RES: log.info("@@@ RECV VMS Server Message: INT_OP_PG_STATE_RES"); break; case CENTER_COMM_DEFINE.INT_OP_VMS_FORM_SAVE: byte[] saveDt = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_DATETIME]; byteBuffer.get(saveDt); // VMS 폼을 데이터베이스에 저장(다운로드 결과는 알수 없음) String command = "form-save"; //String notifyTm = new String(saveDt); String notifyTm = new String(saveDt, StandardCharsets.UTF_8); log.info("@@@ RECV VMS Server Message: INT_OP_VMS_FORM_SAVE: SaveTime: {}", notifyTm); NotifyDto notifyDto1 = NotifyDto.builder() .notify(command) .notifyTm(notifyTm) .notifyCount(0) .notifyMsg(command) .build(); ItsWebSocketMessage socketMessage1 = new ItsWebSocketMessage(command, notifyDto1); try { String jsonData = this.mapper.writeValueAsString(socketMessage1); this.itsWebSocketSessionManager.sendBroadcastMessage(socketMessage1.getCommand(), new TextMessage(jsonData)); } catch(JsonProcessingException e){ log.error("@@@ RECV VMS Server Message: CenterCommServerReceiver: INT_OP_VMS_FORM_SAVE, NotifyDto Json parsing Exception: {}", notifyDto1); } break; case CENTER_COMM_DEFINE.INT_OP_VMS_FORM_DOWNLOAD: count = byteBuffer.get(); // VMS 폼 다운로드 결과 데이터베이스 저장 log.info("@@@ RECV VMS Server Message: INT_OP_VMS_FORM_DOWNLOAD: Count: {} EA", count); NotifyDto notifyDto2 = NotifyDto.builder() .notify("form-download") .notifyTm(ItsUtils.getSysTime()) .notifyCount(0) .notifyMsg("form-download") .build(); ItsWebSocketMessage socketMessage2 = new ItsWebSocketMessage("form-download", notifyDto2); try { String jsonData = this.mapper.writeValueAsString(socketMessage2); this.itsWebSocketSessionManager.sendBroadcastMessage(socketMessage2.getCommand(), new TextMessage(jsonData)); } catch(JsonProcessingException e){ log.error("@@@ RECV VMS Server Message: CenterCommServerReceiver: INT_OP_VMS_FORM_DOWNLOAD, NotifyDto Json parsing Exception: {}", notifyDto2); } /* for (int ii = 0; ii < count; ii++) { vmsId = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_ID]; byte[] downloadDt = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_DATETIME]; byteBuffer.get(vmsId); byteBuffer.get(downloadDt); byte result = byteBuffer.get(); for (int jj = 0; jj < vmsId.length; jj++) { if (vmsId[jj] < '0' || vmsId[jj] > '9') { vmsId[jj] = ' '; } } //log.error("{}, {}, {}, {}", ii+1, new String(vmsId).trim(), new String(downloadDt), result); }*/ break; case CENTER_COMM_DEFINE.INT_OP_VMS_STATE_RES: short total = byteBuffer.getShort(); short error = byteBuffer.getShort(); short normal = byteBuffer.getShort(); short module = byteBuffer.getShort(); count = byteBuffer.get(); log.info("@@@ RECV VMS Server Message: INT_OP_VMS_STATE_RES: total({}), error({}), normal({}), module({}), count: {} EA.", total, error, normal, module, count); // for (int ii = 0; ii < count; ii++) { // vmsId = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_ID]; // byteBuffer.get(vmsId); // byte OprMode = byteBuffer.get(); /* VMS운영모드, 0:auto, 1:Fix */ // byte Comm = byteBuffer.get(); /* 유선통신상태, 0:정상 1:장애 */ // byte Wcomm = byteBuffer.get(); /* 무선통신상태, 0:정상 1:장애 */ // // byte DoorStatus = byteBuffer.get(); /* 도어상태정보코드, 0:열림 1:닫힘 2:알수없음 */ // byte ModulePowerStatus = byteBuffer.get(); /* 모듈전원상태정보코드, 0:켜짐 1:꺼짐 2:알수없음 */ // short BodyTemp = byteBuffer.getShort(); /* 함체온도값(℃), 범위(-128~127) */ // byte LuminanceStatus = byteBuffer.get(); /* 화면의 밝기값 (최대 휘도값을 100으로 했을 때의 백분율 값), 범위(0~100) */ // byte FanStatus = byteBuffer.get(); /* Fan 동작상태정보코드, 0:켜짐, 1:꺼짐 2:알수없음 */ // byte HeaterStatus = byteBuffer.get(); /* Heater 동작상태정보코드, 0:켜짐, 1:꺼짐 2:알수없음 */ // // byte ExternalLightStatus = byteBuffer.get(); /* 선택 외부조명 동작상태정보코드 0:켜짐, 1:꺼짐, 2:자동(공단은 미사용) */ // byte AlarmLightStatus = byteBuffer.get(); /* 선택 경광등 동작상태정보코드 0:켜짐, 1:꺼짐 */ // byte SpeakerStatus = byteBuffer.get(); /* 선택 스피커 동작상태정보코드 0:켜짐, 1:꺼짐 */ // byte[] ControllerCurrentTime = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_DATETIME]; // byteBuffer.get(ControllerCurrentTime); // byte Voltage = byteBuffer.get(); /* 전압, 범위(0~255), 사용안함 */ // // byte ModuleState = byteBuffer.get(); /* 모듈 상태, 0:정상 1:장애 2:알수없음 */ // byte ModuleHorizontal = byteBuffer.get(); /* 가로 모듈수 */ // byte ModuleVertical = byteBuffer.get(); /* 세로 모듈수 */ // byte[] ModuleStatus = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_MODULE_BIT]; /* 모듈 개별 상태, 0:정상 1:장애 2:알수없음 */ // byteBuffer.get(ModuleStatus); // byte PowerCount = byteBuffer.get(); /* 전원 갯수 */ // byte[] PowerStatus = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_POWER_BIT]; /* 전원 개별 상태, 0:켜짐 1:꺼짐 2:알수없음 */ // byteBuffer.get(PowerStatus); // byte[] Dummy = new byte[CENTER_COMM_DEFINE.INT_VMS_STATUE_DUMMY]; /* protocol dummy bytes */ // byteBuffer.get(Dummy); // short ScheduledMessageOperatingTime = byteBuffer.getShort(); /* 필수 계획된 메시지의 동작시간(초) */ // short ModuleOperatingTemperature = byteBuffer.getShort(); /* 필수 모듈 전원이 꺼지는 온도값(℃) */ // short FanOperatingTemperature = byteBuffer.getShort(); /* 필수 Fan 동작 기준 온도값(℃) */ // short HeaterOperatingTemperature = byteBuffer.getShort(); /* 필수 Heater 동작 기준 온도값(℃) */ // short ExternalLightOperatingLuminance = byteBuffer.getShort(); /* 선택 외부전등 동작 기준 휘도값 */ // short ModuleBasicFailureRate = byteBuffer.getShort(); /* 선택 모듈 장애율 (한 개의 모듈을 장애로 처리하기 위한 픽셀의 백분율값) */ // short MaximumRetry = byteBuffer.getShort(); /* 선택 최대 재시도 횟수(회) */ // short ResponseTimeOut = byteBuffer.getShort(); /* 선택 최대응답대기시간 (초) */ // short BlinkingCycleTime = byteBuffer.getShort(); /* 선택 점멸시간 주기 ( 1/10초단위) */ // // for (int jj = 0; jj < vmsId.length; jj++) { // if (vmsId[jj] < '0' || vmsId[jj] > '9') { // vmsId[jj] = ' '; // } // } // //log.info("{}, VmsId: {}, ModuleHor: {}, ModuleVer: {}", ii+1, new String(vmsId).trim(), ModuleHorizontal, ModuleVertical); // } break; default: log.info("RECV VMS Server Message: Other opCode: {}", opCode); break; } } return; } String reqIpAddr = data.getSenderIp(); int reqPort = 4603; /*UnitSystService unitSystService = (UnitSystService) AppUtils.getBean(UnitSystService.class); ConcurrentHashMap untiSystMap = unitSystService.getUntiSystMap(); for (Map.Entry e : untiSystMap.entrySet()) { if (reqIpAddr.equals(e.getValue().getSYST_IP_1())) { reqPort = e.getValue().getPRGM_PORT(); break; } }*/ /*byte opCode = data.getOpCode(); if (opCode == CENTER_COMM_DEFINE.INT_OP_DSRC_CONTROL_REQ) { CENTER_DSRC_REQ_CONTROL req = new CENTER_DSRC_REQ_CONTROL(data.getBody()); log.info("DSRC REQ CONTROL: [{}] [{},{},{},{}], {}", req.getCtlrNmbr(), req.getOperId(), req.getCmdTime(), req.getDeviceType(), req.getControlType(), Thread.currentThread().getName()); int devcType = req.getDeviceType(); int cntlType = req.getControlType(); voDsrcCtlrCntl cntl = new voDsrcCtlrCntl(); cntl.setReq(req); cntl.setReqIpAddress(data.getSender().getAddress().getHostAddress()); cntl.setReqPort(data.getSender().getPort()); cntl.setID(req.getCtlrNmbr()); cntl.setCNTL_DT(SysUtils.getSysTime()); cntl.setDEVC_TYPE(String.valueOf(devcType)); cntl.setCNTL_TYPE(String.valueOf(cntlType)); voDsrcCtlr dsrcCtlr = AppRepository.getInstance().getCtlrMap().get(String.valueOf(req.getCtlrNmbr()).toString()); if (dsrcCtlr == null) { log.info("DSRC REQ CONTROL Unknown DSRC ID: [{}] [{},{},{},{}]", req.getCtlrNmbr(), req.getOperId(), req.getCmdTime(), req.getDeviceType(), req.getControlType()); responseOperator(null, cntl, (byte)0x01); return; } if (dsrcCtlr.getChannel() == null || dsrcCtlr.getNetState() != NET.LOGINED) { // 여기 들어오면 안된다. 운영단말에서 통신이 정상인 것만 제어를 내릴수 있도록 한다. log.error("DSRC REQ CONTROL Not Connect: [{}] [{},{},{},{}]", req.getCtlrNmbr(), req.getOperId(), req.getCmdTime(), req.getDeviceType(), req.getControlType()); responseOperator(dsrcCtlr, cntl, (byte)0x01); return; } // 제어요청 패킷을 만든다 eControlDeviceId controlDeviceId = eControlDeviceId.getByValue(devcType); eControlCommand commandType = eControlCommand.getByValue(cntlType); if (controlDeviceId == null || commandType == null) { log.error("DSRC REQ CONTROL Value Error: [{}] [{},{},{},{}]", req.getCtlrNmbr(), req.getOperId(), req.getCmdTime(), req.getDeviceType(), req.getControlType()); responseOperator(dsrcCtlr, cntl, (byte)0x01); return; } log.warn("{}, {}, controlDeviceId: {}, commandType: {}", dsrcCtlr.getID(), dsrcCtlr.getRSE_ID(), controlDeviceId.toString(), commandType.toString()); boolean res = ControlDeviceService.getInstance().requestSubscriptionDeviceCommand(true, dsrcCtlr, dsrcCtlr.getChannel(), controlDeviceId.getValue(), commandType.getValue()); if (res) { log.info("DSRC REQ CONTROL SEND OK: [{}] [{},{},{},{}]", req.getCtlrNmbr(), req.getOperId(), req.getCmdTime(), req.getDeviceType(), req.getControlType()); responseOperator(dsrcCtlr, cntl, (byte)0x00); } else { log.error("DSRC REQ CONTROL SEND Error: [{}] [{},{},{},{}]", req.getCtlrNmbr(), req.getOperId(), req.getCmdTime(), req.getDeviceType(), req.getControlType()); responseOperator(dsrcCtlr, cntl, (byte)0x01); } } else { log.error("UDP RECV UNKNOWN MESSAGE: {}", opCode); }*/ } /* private int responseOperator(voDsrcCtlr obj, voDsrcCtlrCntl cntl, byte error) { CenterCommResponseService responseService = (CenterCommResponseService) AppUtils.getBean(CenterCommResponseService.class); return responseService.response(obj, cntl, error); }*/ }