Browse Source

second commit

shjung 3 years ago
parent
commit
68a822ffe5
41 changed files with 848 additions and 200 deletions
  1. 4 10
      src/main/java/com/its/vds/entity/TbVdsCtlr.java
  2. 3 2
      src/main/java/com/its/vds/service/VdsCtlrService.java
  3. 3 1
      src/main/java/com/its/vds/xnettcp/vds/VdsTcpClient.java
  4. 3 1
      src/main/java/com/its/vds/xnettcp/vds/VdsTcpClientBootstrapFactory.java
  5. 6 5
      src/main/java/com/its/vds/xnettcp/vds/VdsTcpClientCommService.java
  6. 2 2
      src/main/java/com/its/vds/xnettcp/vds/codec/VdsTcpClientDecoder.java
  7. 20 5
      src/main/java/com/its/vds/xnettcp/vds/handler/VdsTcpClientInboundHandler.java
  8. 5 0
      src/main/java/com/its/vds/xnettcp/vds/process/JobProtocol.java
  9. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_ACK.java
  10. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Abort.java
  11. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_CheckEcho.java
  12. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_CheckMemory.java
  13. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_CheckSeq.java
  14. 70 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Data.java
  15. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Downloading.java
  16. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Image.java
  17. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Initialize.java
  18. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Length.java
  19. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_NAK.java
  20. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Online.java
  21. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_RTC.java
  22. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_RePosition.java
  23. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Reset.java
  24. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_SetRunTemp.java
  25. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Speed.java
  26. 35 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Temperature.java
  27. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Traffic.java
  28. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Uploading.java
  29. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Usage.java
  30. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Validation.java
  31. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Vehicle.java
  32. 18 0
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Version.java
  33. 7 8
      src/main/java/com/its/vds/xnettcp/vds/process/VdsData.java
  34. 146 138
      src/main/java/com/its/vds/xnettcp/vds/process/VdsDataProcess.java
  35. 1 0
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsProtocol.java
  36. 17 14
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqFramePacket.java
  37. 16 6
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqImage.java
  38. 2 3
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqRTC.java
  39. 16 1
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsResFramePacket.java
  40. 1 1
      src/main/resources/application.yml
  41. 95 3
      src/test/java/com/its/app/VdsCommServerApplicationTests.java

+ 4 - 10
src/main/java/com/its/vds/entity/TbVdsCtlr.java

@@ -57,11 +57,10 @@ public class TbVdsCtlr {
 
 	private boolean dump = false;
 
-	VdsReqSynchronize reqSynchronize = null;
-	VdsReqData reqData = null;
-	VdsReqTemperature reqTemperature = null;
-	VdsReqTraffic reqTraffic = null;
-	VdsReqReset reqReset = null;
+	private VdsReqSynchronize reqSynchronize = null;
+	private VdsReqData reqData = null;
+	private VdsReqTemperature reqTemperature = null;
+	private VdsReqTraffic reqTraffic = null;
 
 	public TbVdsCtlr() {
 		this.vdsDtctMap = Collections.synchronizedMap(new HashMap<String, TbVdsDtct>());
@@ -147,12 +146,7 @@ public class TbVdsCtlr {
 			this.reqTraffic = new VdsReqTraffic((short)this.GROUP_NO, (short)this.VDS_CTLR_LOCAL_NO);
 			this.reqTraffic.makeCRC();
 		}
-		if (this.reqReset == null) {
-			this.reqReset = new VdsReqReset((short)this.GROUP_NO, (short)this.VDS_CTLR_LOCAL_NO);
-			this.reqReset.makeCRC();
-		}
 
-		//reqTraffic
 	}
 
 	/**

+ 3 - 2
src/main/java/com/its/vds/service/VdsCtlrService.java

@@ -53,9 +53,10 @@ public class VdsCtlrService {
 
     public void initVdsCtlr() {
         try {
-            for (Map.Entry<String, TbVdsCtlr> obj : AppRepository.getInstance().getCtlrMap().entrySet()) {
+            for (Map.Entry<String, TbVdsCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
                 // 제어기가 삭제됐다고 초기화
-                obj.getValue().setDEL_YN("Y");
+                TbVdsCtlr obj = e.getValue();
+                obj.setDEL_YN("Y");
             }
         }
         catch (Exception e) {

+ 3 - 1
src/main/java/com/its/vds/xnettcp/vds/VdsTcpClient.java

@@ -6,6 +6,7 @@ import com.its.vds.xnettcp.vds.codec.VdsTcpClientDecoder;
 import com.its.vds.xnettcp.vds.codec.VdsTcpClientEncoder;
 import com.its.vds.xnettcp.vds.handler.VdsTcpClientIdleHandler;
 import com.its.vds.xnettcp.vds.handler.VdsTcpClientInboundHandler;
+import com.its.vds.xnettcp.vds.process.VdsDataProcess;
 import io.netty.bootstrap.Bootstrap;
 import io.netty.channel.*;
 import io.netty.channel.socket.SocketChannel;
@@ -29,6 +30,7 @@ public class VdsTcpClient implements Callable<Object> {
 
     private final TbVdsCtlr controller;
     private final LocalCommConfig commConfig;
+    private final VdsDataProcess vdsDataProcess;
     private final VdsTcpClientBootstrapFactory bootstrapFactory;
 
     private Bootstrap bootstrap = null;
@@ -60,7 +62,7 @@ public class VdsTcpClient implements Callable<Object> {
                     }
                     ch.pipeline().addLast("vdsClientIdleHandler",    new VdsTcpClientIdleHandler(commConfig.getReaderIdleTime(), commConfig.getWriterIdleTime(), commConfig.getAllIdleTime(), TimeUnit.SECONDS));
                     ch.pipeline().addLast("vdsClientDecoder",        new VdsTcpClientDecoder());            // Decoding handler
-                    ch.pipeline().addLast("vdsClientInboundHandler", new VdsTcpClientInboundHandler());     // Packet Inbound handler
+                    ch.pipeline().addLast("vdsClientInboundHandler", new VdsTcpClientInboundHandler(vdsDataProcess));     // Packet Inbound handler
                     ch.pipeline().addLast("vdsClientEncoder",        new VdsTcpClientEncoder());            // Encoding handler
                 }
             });

+ 3 - 1
src/main/java/com/its/vds/xnettcp/vds/VdsTcpClientBootstrapFactory.java

@@ -4,6 +4,7 @@ import com.its.app.utils.NettyUtils;
 import com.its.vds.xnettcp.vds.codec.VdsTcpClientDecoder;
 import com.its.vds.xnettcp.vds.codec.VdsTcpClientEncoder;
 import com.its.vds.xnettcp.vds.handler.VdsTcpClientInboundHandler;
+import com.its.vds.xnettcp.vds.process.VdsDataProcess;
 import io.netty.bootstrap.Bootstrap;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelInitializer;
@@ -21,6 +22,7 @@ public class VdsTcpClientBootstrapFactory {
     private final int workerThread;
     private final int connectTimeout;
     private final boolean isLogging;
+    private final VdsDataProcess vdsDataProcess;
     private EventLoopGroup nioEventLoopGroup = null;
 
     public Bootstrap createBootstrap() {
@@ -51,7 +53,7 @@ public class VdsTcpClientBootstrapFactory {
                 }
                 //ch.pipeline().addLast("vdsClientIdleHandler",    new VdsTcpClientIdleHandler(0, 0, 0, TimeUnit.SECONDS));
                 ch.pipeline().addLast("vdsClientDecoder",        new VdsTcpClientDecoder());            // Decoding handler
-                ch.pipeline().addLast("vdsClientInboundHandler", new VdsTcpClientInboundHandler());     // Packet Inbound handler
+                ch.pipeline().addLast("vdsClientInboundHandler", new VdsTcpClientInboundHandler(vdsDataProcess));     // Packet Inbound handler
                 ch.pipeline().addLast("vdsClientEncoder",        new VdsTcpClientEncoder());            // Encoding handler
             }
         });

+ 6 - 5
src/main/java/com/its/vds/xnettcp/vds/VdsTcpClientCommService.java

@@ -3,6 +3,7 @@ package com.its.vds.xnettcp.vds;
 import com.its.vds.config.LocalCommConfig;
 import com.its.vds.entity.TbVdsCtlr;
 import com.its.vds.global.AppRepository;
+import com.its.vds.xnettcp.vds.process.VdsDataProcess;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -24,13 +25,15 @@ import java.util.concurrent.Future;
 public class VdsTcpClientCommService {
 
     private final LocalCommConfig commConfig;
+    private final VdsDataProcess vdsDataProcess;
+
     private VdsTcpClientBootstrapFactory bootstrapFactory;
     private ExecutorService executorService= Executors.newFixedThreadPool(1);
     private List<VdsTcpClient> clientTasks = Collections.synchronizedList(new ArrayList());
 
     @PostConstruct
     void init() {
-        this.bootstrapFactory = new VdsTcpClientBootstrapFactory(1, this.commConfig.getConnectTimeout(), this.commConfig.isCommLogging());
+        this.bootstrapFactory = new VdsTcpClientBootstrapFactory(1, this.commConfig.getConnectTimeout(), this.commConfig.isCommLogging(), vdsDataProcess);
     }
 
     public void run() {
@@ -41,8 +44,8 @@ public class VdsTcpClientCommService {
          */
         for (Map.Entry<String, TbVdsCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
             TbVdsCtlr obj = e.getValue();
-            if (obj.getDEL_YN().equals("N") && obj.getVALD_YN().equals("Y")) {
-                VdsTcpClient vdsClient = new VdsTcpClient(obj, this.commConfig, this.bootstrapFactory);
+            if ((obj.getDEL_YN() != null && obj.getDEL_YN().equals("N")) && (obj.getVALD_YN() != null && obj.getVALD_YN().equals("Y"))) {
+                VdsTcpClient vdsClient = new VdsTcpClient(obj, this.commConfig, this.vdsDataProcess, this.bootstrapFactory);
                 this.clientTasks.add(vdsClient);
             }
         }
@@ -64,8 +67,6 @@ public class VdsTcpClientCommService {
                 obj.getChannel().close();
             }
         }
-
         this.bootstrapFactory.getEventLoopGroup().shutdownGracefully();
-        log.error("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
     }
 }

+ 2 - 2
src/main/java/com/its/vds/xnettcp/vds/codec/VdsTcpClientDecoder.java

@@ -76,7 +76,7 @@ public class VdsTcpClientDecoder extends ByteToMessageDecoder {
                     if (foundDle) {
                         foundDle = false;
                         if (data == VdsProtocol.vds_DLE) {
-                            // Skip Data
+                            // Skip DLE Stuffing Data
                             log.warn("RECV_0: [{}]. ReadableBytes: {} Bytes, ReadIndex: {}, DLE Stuffing Data Recv.", ipAddress, readableBytes, readIdx);
                         } else if (data == VdsProtocol.vds_STX) {
                             // Packet
@@ -101,7 +101,7 @@ public class VdsTcpClientDecoder extends ByteToMessageDecoder {
                             byteBuf.markReaderIndex();
                             byteBuf.discardReadBytes();
 
-                            VdsResFramePacket packet = new VdsResFramePacket(packets, msgSize);
+                            VdsResFramePacket packet = new VdsResFramePacket(obj, packets, msgSize);
                             log.info("OnePacket: {} Bytes, {}", packet.getByteBuffer().array().length, SysUtils.byteArrayToHex(packet.getByteBuffer().array()));
                             list.add(packet);
                             break;

+ 20 - 5
src/main/java/com/its/vds/xnettcp/vds/handler/VdsTcpClientInboundHandler.java

@@ -1,17 +1,32 @@
 package com.its.vds.xnettcp.vds.handler;
 
+import com.its.app.utils.NettyUtils;
+import com.its.vds.xnettcp.vds.process.VdsData;
+import com.its.vds.xnettcp.vds.process.VdsDataProcess;
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 
 @Slf4j
+@RequiredArgsConstructor
 @ChannelHandler.Sharable
-public class VdsTcpClientInboundHandler extends SimpleChannelInboundHandler<Object> {
+public class VdsTcpClientInboundHandler extends ChannelInboundHandlerAdapter {
 
-    @Override
-    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object msg) {
-        log.info("channelRead0: {}", msg);
+    private final VdsDataProcess vdsDataProcess;
+
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+
+        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());
+        if (!(msg instanceof VdsResFramePacket)) {
+            log.error("[{}] | Received Data is not VdsResFramePacket Object", NettyUtils.getRemoteIpAddress(ctx.channel()));
+            return;
+        }
+
+        VdsResFramePacket resFramePacket = (VdsResFramePacket)msg;
+        this.vdsDataProcess.add(new VdsData(resFramePacket.getVdsObj(), ipAddress, ctx, resFramePacket));
     }
 
 }

+ 5 - 0
src/main/java/com/its/vds/xnettcp/vds/process/JobProtocol.java

@@ -0,0 +1,5 @@
+package com.its.vds.xnettcp.vds.process;
+
+public interface JobProtocol {
+	int parse();
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_ACK.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_ACK implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Abort.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Abort implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_CheckEcho.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_CheckEcho implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_CheckMemory.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_CheckMemory implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_CheckSeq.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_CheckSeq implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 70 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Data.java

@@ -0,0 +1,70 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Data implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		// 교통정보 데이터 수신
+		if (this.packet == null || this.packet.getVdsObj() == null) {
+			log.error("Job_Data, packet or object data null");
+			return 0;
+		}
+
+		byte[] body = this.packet.getBody();
+		if (body == null || body.length < 5) {
+			log.error("Job_Data, [{}]: Data Length Error, {}", this.packet.getObjectInfo(), (body == null) ? 0 : body.length);
+			return 0;
+		}
+
+		int FrameNo = body[0];
+		byte stts1  = body[1];
+		byte stts2  = body[2];
+		byte stts3  = body[3];
+		byte stts4  = body[4];
+
+		// 차로별 교통 정보 : 9 Byte * (차로 수)
+
+//		Byte 7		Lane 1 교통량 (Volume)
+//		Byte 8		Lane 1 평균 속도
+//		Byte 9		Lane 1 점유율 정수부분 (Occupancy) (점유율 소수2자리까지 표현)
+//		Byte 10		Lane 1 점유율 소수부분 (Occupancy)
+//		Byte 11		Lane 1 평균 차량 길이 (dm : decimal meter, 1 dm = 1/10 m)
+//		Byte 12		Lane 1 평균 차두시간 (1byte 정수)
+//		Byte 13		Lane 1 공간 점유율 정수부분 (Space   Occupancy)	(점유율 소수2자리까지 표현)
+//		Byte 14		Lane 1 공간 점유율 소수부분 (Space   Occupancy)
+//		Byte 15		Lane 1 공간 평균속도 (1byte 정수)
+
+		int idx;
+		int laneCnt = (body.length - 5) / 9;
+		int   tfvl, spd, occ1, occ2, len, hdr, spc_occ1, spc_occ2, spc_spd;
+		float occ, spc_occ;
+		for (int ii = 0; ii < laneCnt; ii++) {
+			idx = (ii * 9) + 5;
+			tfvl = body[idx+0];
+			spd = body[idx+1];
+			occ1 = body[idx+2];
+			occ2 = body[idx+3];
+			len = body[idx+4];
+			hdr = body[idx+5];
+			spc_occ1 = body[idx+6];
+			spc_occ2 = body[idx+7];
+			spc_spd = body[idx+8];
+
+			occ  = (float)(occ1 + (occ2 * 0.01));
+			spc_occ  = (float)(spc_occ1 + (spc_occ2 * 0.01));
+
+			log.error("Job_Data, [{}]: Lane:{}, TFVL:{}, SPD:{}, OCC:{}, LEN:{}, HDR:{}, SOCC:{}, SSPD:{}",
+					this.packet.getObjectInfo(), ii+1, tfvl, spd, occ, len, hdr, spc_occ, spc_spd);
+		}
+		return 1;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Downloading.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Downloading implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Image.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Image implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Initialize.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Initialize implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Length.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Length implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_NAK.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_NAK implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Online.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Online implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_RTC.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_RTC implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_RePosition.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_RePosition implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Reset.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Reset implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_SetRunTemp.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_SetRunTemp implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Speed.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Speed implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 35 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Temperature.java

@@ -0,0 +1,35 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Temperature implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		// 온도 & 전압 수신
+		if (this.packet == null || this.packet.getVdsObj() == null) {
+			log.error("Job_Temperature, packet or object data null");
+			return 0;
+		}
+
+		byte[] body = this.packet.getBody();
+		if (body == null || body.length != 3) {
+			log.error("Job_Temperature, [{}]: Data Length Error, {}", this.packet.getObjectInfo(), (body == null) ? 0 : body.length);
+			return 0;
+		}
+
+		int CBOX_TMPR = body[0];
+		int InputVoltage = (int)(body[1] & 0xFF);
+		int OutputVoltage = (int)(body[2] & 0xFF);
+		log.info("Job_Temperature, [{}]: {}, {}, {}", this.packet.getObjectInfo(), CBOX_TMPR, InputVoltage, OutputVoltage);
+		this.packet.getVdsObj().getStts().setCBOX_TMPR(CBOX_TMPR);
+		return 1;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Traffic.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Traffic implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Uploading.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Uploading implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Usage.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Usage implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Validation.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Validation implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Vehicle.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Vehicle implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 18 - 0
src/main/java/com/its/vds/xnettcp/vds/process/Job_Version.java

@@ -0,0 +1,18 @@
+package com.its.vds.xnettcp.vds.process;
+
+import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RequiredArgsConstructor
+public class Job_Version implements JobProtocol {
+
+	private final VdsResFramePacket packet;
+
+	@Override
+	public int parse() {
+		return 0;
+	}
+
+}

+ 7 - 8
src/main/java/com/its/vds/xnettcp/vds/process/VdsData.java

@@ -1,21 +1,20 @@
 package com.its.vds.xnettcp.vds.process;
 
+import com.its.vds.entity.TbVdsCtlr;
 import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
 import io.netty.channel.ChannelHandlerContext;
 import lombok.Getter;
+import lombok.RequiredArgsConstructor;
 import lombok.Setter;
 
 @Getter
 @Setter
+@RequiredArgsConstructor
 public class VdsData {
 
-    private String ipAddress;
-    private ChannelHandlerContext ctx;
-    private VdsResFramePacket data;
+    private final TbVdsCtlr obj;
+    private final String ipAddress;
+    private final ChannelHandlerContext ctx;
+    private final VdsResFramePacket data;
 
-    public VdsData(String ipAddress, ChannelHandlerContext ctx, VdsResFramePacket data) {
-        this.ipAddress = ipAddress;
-        this.ctx       = ctx;
-        this.data      = data;
-    }
 }

+ 146 - 138
src/main/java/com/its/vds/xnettcp/vds/process/VdsDataProcess.java

@@ -4,10 +4,8 @@ import com.its.app.AppUtils;
 import com.its.app.utils.SysUtils;
 import com.its.vds.config.ThreadPoolInitializer;
 import com.its.vds.entity.TbVdsCtlr;
-import com.its.vds.global.AppRepository;
 import com.its.vds.xnettcp.vds.protocol.VdsProtocol;
 import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
-import io.netty.channel.Channel;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
 import org.springframework.stereotype.Service;
@@ -18,7 +16,7 @@ import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
 
 @Slf4j
-@Service("tcpServerDataProcess")
+@Service
 public class VdsDataProcess {
 
     public static LinkedBlockingQueue<VdsData> SERVER_DATA_QUEUE = new LinkedBlockingQueue<>(1000);
@@ -30,185 +28,196 @@ public class VdsDataProcess {
     }
 
     public void run() {
-        log.info("TcpServerDataProcess.run: Start.");
+        log.info("VdsDataProcess.run: Start.");
         if (this.MAX_CORE < 8) {
             this.MAX_CORE = 8;
         }
         ThreadPoolInitializer poolInitializer = (ThreadPoolInitializer) AppUtils.getBean(ThreadPoolInitializer.class);
         int executePool = Math.max(this.MAX_CORE, poolInitializer.getWork());
         for (int ii = 0; ii < executePool; ii++) {
-            log.info("TcpServerDataProcess.Task: {}", ii);
+            log.info("VdsDataProcess.Task: {}", ii);
             this.taskExecutor.execute(() -> {
                 while (true) {
+                    VdsData serverData = null;
                     try {
-                        VdsData serverData = VdsDataProcess.SERVER_DATA_QUEUE.take();
-                        if (serverData != null) {
-                            VdsDataTask handler = (VdsDataTask) AppUtils.getBean(VdsDataTask.class);
-                            handler.run(this, serverData);
-                        }
-                        else {
-                            log.error("TcpServerDataProcess.Task: Received data null");
-                        }
-                    }
-                    catch (Exception e) {
-                        log.error("TcpServerDataProcess.Task: Exception: {}", e.getMessage(), e);
+                        serverData = VdsDataProcess.SERVER_DATA_QUEUE.take();
+                        VdsDataTask handler = (VdsDataTask) AppUtils.getBean(VdsDataTask.class);
+                        handler.run(this, serverData);
+                    } catch (InterruptedException e) {
+                        log.error("VdsDataProcess.Task: Received data null");
                     }
                 }
             });
         }
 
-        log.info("TcpServerDataProcess.run: ..End.");
+        log.info("VdsDataProcess.run: ..End.");
     }
 
     public void process(VdsData data) {
 
         String ipAddress = data.getIpAddress();
-        TbVdsCtlr obj = AppRepository.getInstance().getCtlrIpMap().get(ipAddress);
+        TbVdsCtlr obj = data.getObj();
+        if (obj == null) {
+            log.error("VdsDataProcess.process: [{}] Unknown ip address data packet", data.getIpAddress());
+            return;
+        }
+
+        MDC.put("id", obj.getLogKey());
         try {
-            if (obj == null) {
-                log.error("TcpServerDataProcess.process: [{}] Unknown ip address data packet", data.getIpAddress());
+            VdsResFramePacket framePacket = data.getData();
+            byte opCode = framePacket.getOpCode();
+            int groupNo = framePacket.getHead().getGroupNo();
+            int ctrlNo  = framePacket.getHead().getControllerNo();
+            if (groupNo != obj.getGROUP_NO() || ctrlNo != obj.getVDS_CTLR_LOCAL_NO()) {
+                log.error("VdsDataProcess.process: ID: {}, ChannelNo, Controller No Miss Matched: [{}]-[{}], [{}]-[{}]",
+                        obj.getVDS_CTLR_NMBR(), groupNo, obj.getGROUP_NO(), ctrlNo, obj.getVDS_CTLR_LOCAL_NO());
+                //return;
+            }
+            log.info("VdsDataProcess.process: {}, {}, ThreadId: {}", ipAddress, VdsProtocol.getOpCodeName(opCode), Thread.currentThread().getId());
+            if (!checkStatus(obj, framePacket)) {
                 return;
             }
 
-            MDC.put("id", obj.getLogKey());
-
-//            JobProtocol jobProtcol = null;
-//            Channel channel = data.getCtx().channel();
-//            VdsResFramePacket body = data.getData();
-//            byte opCode = body.getHead().getOpCode();
-//            int groupNo = (int)body.getHead().getGroupNo();
-//            int ctrlNo  = (int)body.getHead().getCtlrNo();
-//            if (groupNo != obj.getGROUP_NO() || ctrlNo != obj.getVDS_CTLR_LOCAL_NO()) {
-//                log.error("TcpServerDataProcess.process: ID: {}, ChannelNo, Controller No Miss Matched: [{}]-[{}], [{}]-[{}]",
-//                        obj.getVDS_CTLR_NMBR(), groupNo, obj.getGROUP_NO(), ctrlNo, obj.getVDS_CTLR_LOCAL_NO());
-//                return;
-//            }
-//
-//            log.info("TcpServerDataProcess.process: {}, {}, ThreadId: {}", ipAddress, VDS_HEAD.getOpCodeName(opCode), Thread.currentThread().getId());
-//
-//            if (!checkStatus(obj, body, channel)) {
-//                return;
-//            }
-//
-//            switch (opCode) {
-//                case VDS_HEAD.evds_CSN:
-//                    jobProtcol = new JobProtocol_0xFF(channel, body, obj);
-//                    break;
-//                case VDS_HEAD.evds_Traffic:
-//                    jobProtcol = new JobProtocol_0x04(channel, body, obj);
+            JobProtocol jobProtocol = null;
+            switch (opCode) {
+                case VdsProtocol.vds_Temperature:   //    = (byte)0x1E;   // 제어기 상태 함체온도 및 입출력전압 요청 #30[0x1E] 센터→로컬 함체온도/입출력전압
+                    jobProtocol = new Job_Temperature(framePacket);
+                    break;
+                case VdsProtocol.vds_Data:          //    = (byte)0x04;   // VDS 데이터 요구 (Data Request) 데이터 요구 #4[0x04] 센터→로컬 교통data(교통량,점유율,차량길이,속도)
+                    jobProtocol = new Job_Data(framePacket);
+                    break;
+
+                case VdsProtocol.vds_Traffic:       //    = (byte)0x07;   // VDS 데이터 요구 (Data Request) 누적 교통량 데이터 요구 #7[0x07] 센터→로컬 교통량data
+                    jobProtocol = new Job_Traffic(framePacket);
+                    break;
+                case VdsProtocol.vds_ACK:           //    = (byte)0x70;   // 센터의 명령을 현장제어기가 정상적으로 수행을 완료했으나, 전송할 결과가 없을 때 클라이언트가 전송하는 Packet임.
+                    jobProtocol = new Job_ACK(framePacket);
+                    break;
+
+                case VdsProtocol.vds_Speed:         //    = (byte)0x05;   // VDS 데이터 요구 (Data Request) 속도 데이터 요구 #5[0x05] 센터→로컬 특정차로 속도data
+                    jobProtocol = new Job_Speed(framePacket);
+                    break;
+
+                case VdsProtocol.vds_Image:         //    = (byte)0x16;   // VDS 데이터 요구 (Data Request) 화상이미지 요구 #22[0x16] 센터→로컬 이미지data
+                    jobProtocol = new Job_Image(framePacket);
+                    break;
+                case VdsProtocol.vds_Vehicle:       //    = (byte)0x17;   // VDS 데이터 요구 (Data Request) 개별차량 데이터 요구 #23[0x17] 센터→로컬 개별차량 data
+                    jobProtocol = new Job_Vehicle(framePacket);
+                    break;
+                case VdsProtocol.vds_Length:        //    = (byte)0x06;   // VDS 데이터 요구 (Data Request) 차량 길이 데이터 요구 #6[0x06] 센터→로컬 특정차로 차량길이data
+                    jobProtocol = new Job_Length(framePacket);
+                    break;
+
+                case VdsProtocol.vds_NAK:           //    = (byte)0x71;   // 서버의 명령에 오류가 있을 경우 클라이언트가 전송하는 Packet임.
+                    jobProtocol = new Job_NAK(framePacket);
+                    break;
+
+                case VdsProtocol.vds_Validation:    //    = (byte)0x0B;   // 제어기 상태 제어기 Validation #11[0x0B] 센터→로컬 H/W check 결과
+                    jobProtocol = new Job_Validation(framePacket);
+                    break;
+
+//                case VdsProtocol.vds_Reset:         //    = (byte)0x0C;   // 제어기 상태 제어기 Reset #12[0x0C] 센터→로컬 ACK/NAK
+//                    jobProtocol = new Job_Reset(framePacket);
 //                    break;
-//                case VDS_HEAD.evds_Status:
-//                case VDS_HEAD.evds_Initialize:
-//                    jobProtcol = new JobProtocol_0x0B(channel, body, obj);
+//                case VdsProtocol.vds_Initialize:    //    = (byte)0x0D;   // 제어기 상태 제어기 Initialize #13[0x0D] 센터→로컬 ACK/NAK
+//                    jobProtocol = new Job_Initialize(framePacket);
 //                    break;
-//                case VDS_HEAD.evds_Temperature:
-//                    jobProtcol = new JobProtocol_0x30(channel, body, obj);
+//                case VdsProtocol.vds_Downloading:   //    = (byte)0x0E;   // 파라미터 Download 파라미터 Downloading #14[0x0E] 센터→로컬 ACK/NAK
+//                    jobProtocol = new Job_Downloading(framePacket);
 //                    break;
-//                case VDS_HEAD.evds_Reset:
-//                    jobProtcol = new JobProtocol_0x0C(channel, body, obj);
-//                    break;
-//                case VDS_HEAD.evds_ParamDownload:
-//                    jobProtcol = new JobProtocol_0x0E(channel, body, obj);
-//                    break;
-//                case VDS_HEAD.evds_ParamUpload:
-//                    jobProtcol = new JobProtocol_0x0F(channel, body, obj);
-//                    break;
-//                case VDS_HEAD.evds_IndividualVehicle:
-//                    jobProtcol = new JobProtocol_0x16(channel, body, obj);
-//                    break;
-//                case VDS_HEAD.evds_StopImage:
-//                    jobProtcol = new JobProtocol_0x17(channel, body, obj);
+
+                case VdsProtocol.vds_Uploading:     //    = (byte)0x0F;   // 파라미터 Upload 파라미터 Uploading #15[0x0F] 센터→로컬 파라미터값
+                    jobProtocol = new Job_Uploading(framePacket);
+                    break;
+                case VdsProtocol.vds_Online:        //    = (byte)0x11;   // 온라인 상태조사 온라인 상태조사 #17[0x11] 센터→로컬 Passed Time
+                    jobProtocol = new Job_Online(framePacket);
+                    break;
+//                case VdsProtocol.vds_CheckMemory:   //    = (byte)0x12;   // 원격진단 메모리 Check #18[0x12] 센터→로컬 ACK/NAK
+//                    jobProtocol = new Job_CheckMemory(framePacket);
 //                    break;
-//                case VDS_HEAD.evds_Speed:
-//                case VDS_HEAD.evds_Length:
-//                case VDS_HEAD.evds_Volume:
-//                case VDS_HEAD.evds_OnlineStatus:
-//                case VDS_HEAD.evds_MemoryStatus:
-//                case VDS_HEAD.evds_MessageEcho:
-//                case VDS_HEAD.evds_SendSequenceNmbr:
-//                case VDS_HEAD.evds_Version:
-//                case VDS_HEAD.evds_ReverseDetect:
-//                case VDS_HEAD.evds_CommSessionValid:
-//                    jobProtcol = new JobProtocol_0x00(channel, body, obj);
+
+//                case VdsProtocol.vds_RTC:           //    = (byte)0x18;   // 제어기 상태 RTC 변경 #24[0x18] 센터→로컬 ACK/NAK
+//                    jobProtocol = new Job_RTC(framePacket);
 //                    break;
-//                default:
+               case VdsProtocol.vds_CheckEcho:     //    = (byte)0x13;   // 원격진단 Echo Check #19[0x13] 센터→로컬 Echo메시지
+                    jobProtocol = new Job_CheckEcho(framePacket);
+                    break;
+                case VdsProtocol.vds_CheckSeq:      //    = (byte)0x14;   // 원격진단 순번 Check #20[0x14] 센터→로컬 수치처리 결과값
+                    jobProtocol = new Job_CheckSeq(framePacket);
+                    break;
+                case VdsProtocol.vds_Version:       //    = (byte)0x15;   // 원격진단 VDS Version 요청 #21[0x15] 센터→로컬 version정보
+                    jobProtocol = new Job_Version(framePacket);
+                    break;
+                case VdsProtocol.vds_Usage:         //    = (byte)0x19;   // 기타 사용/사용불가 설정 #25[0x19] 운영단말→수집서버 사용여부 설정결과값
+                    jobProtocol = new Job_Usage(framePacket);
+                    break;
+//                case VdsProtocol.vds_SetRunTemp:    //    = (byte)0x20;   // 기타 Fan/Heater 동작온도설정 #26[0x20] 센터→로컬 ACK/NAK
+//                    jobProtocol = new Job_SetRunTemp(framePacket);
 //                    break;
-//            }
-//
-//            if (jobProtcol != null) {
-//                if (jobProtcol.parseProtocol() < 0) {
-//                    /*channel.disconnect();
-//                    channel.close();*/
-//                }
-//            }
-//            else {
-//                log.error("[{}], UNKNOWN OP_CODE: {}", opCode, ipAddress);
-//            }
-        } catch (Exception e) {
-            log.error("TcpServerDataProcess.process: Exception: {}", e.toString());
+                case VdsProtocol.vds_Abort:         //    = (byte)0x72;   // 클라이언트(서버)가 전송하는 데이터가 필요 없을 경우 서버(클라이언트)가 클라이언트(서버)에게 현재 전송중인 데이터를 중단하도록 하는 명령임
+                    jobProtocol = new Job_Abort(framePacket);
+                    break;
+                case VdsProtocol.vds_RePosition:    //    = (byte)0x73;   // 클라이언트가 전송하는 데이터의 특정 위치부터 다시 전송하도록 하는 명령임.
+                    jobProtocol = new Job_RePosition(framePacket);
+                    break;
+            }
+
+            if (jobProtocol != null) {
+                jobProtocol.parse();
+            }
+        } finally {
+            MDC.remove(obj.getLogKey());
+            MDC.clear();
         }
-        MDC.remove(obj.getLogKey());
-        MDC.clear();
     }
 
-    protected boolean checkStatus(TbVdsCtlr obj, VdsResFramePacket packet, Channel channel) {
+    protected boolean checkStatus(TbVdsCtlr obj, VdsResFramePacket packet) {
         String opCodeName = VdsProtocol.getOpCodeName(packet.getHead().getOpCode());
         log.info("RECV_P: [{}], RECV.{}, [{}]", obj.getVDS_CTLR_IP(), opCodeName, obj.getVDS_CTLR_NMBR());
 
-//        if (packet.getHead().getResultCode() != 0x00) {
-//            switch(packet.getHead().getResultCode())
-//            {
-//                case 0x01: log.error("[{}], RECV .Result Error_0x01,내부 시스템 장애로 인한 수행실패, {}", 					obj.getVDS_CTLR_NMBR(), channel); break;
-//                case 0x02: log.error("[{}], RECV .Result Error_0x02,OP code가   잘못된 경우, {}", 						 	obj.getVDS_CTLR_NMBR(), channel); break;
-//                case 0x03: log.error("[{}], RECV .Result Error_0x03,CSN(Controller Station Number)값이 잘못된 경우, {}", 	obj.getVDS_CTLR_NMBR(), channel); break;
-//                case 0x04: log.error("[{}], RECV .Result Error_0x04,데이터 길이 정보가 잘못된 경우, {}", 					obj.getVDS_CTLR_NMBR(), channel); break;
-//                case 0x05: log.error("[{}], RECV .Result Error_0x05,필드 값 범위 초과되었거나 정의된 값이 아닌 경우, {}",   obj.getVDS_CTLR_NMBR(), channel); break;
-//                case 0x06: log.error("[{}], RECV .Result Error_0x06,요청된 데이터가 준비되지 않음, {}", 					obj.getVDS_CTLR_NMBR(), channel); break;
-//                case 0x07: log.error("[{}], RECV .Result Error_0x07,트랜잭션 타임아웃 발생함, {}", 						 	obj.getVDS_CTLR_NMBR(), channel); break;
-//                default:   log.error("[{}], RECV .Result Error_0xFF,알수없음, {}", 									 	    obj.getVDS_CTLR_NMBR(), channel); break;
-//            }
-//            return false;
-//        }
-
         /*
          * VDS Status Update
          */
-        // 0 Long Power Fail. 2초를 초과한 시간 동안 POWER   FAIL 이 발생한 경우 1로 설정.
-        // 1 Short Power Fail.2초 이하의 시간 동안 POWER FAIL 이   발생한 경우 1로 설정.
-        // 2 Default Parameter. 파라미터 RAM 이 기본값을 가지고   있어, HOST 로부터 파라미터 다운로드가 필요한 경우 1로   설정.
-        // 3 Received   Broadcast Message(동기화 명령은 제외). HOST 로부터 전역주소 0xFFFFFFFF를 수신한 경우 1로 설정.
-        // 4 Auto Resynchronization. HOST 로부터 SYNC 명령을 받지 못한 경우, 일정시간 이후(기본1초) 제어기 스스로   동기화한 경우 1로 설정.
-        // 5 FRONT DOOR   OPENED. 앞문이 개방된 경우 1로   설정.
-        // 6 REAR DOOR OPENED.   뒷문이 개방된 경우 1로 설정.
-        // 7 FAN OPERATED. 팬이 작동된 경우 1로 설정.
-        // 8 HEATER OPERATED. 히터가 작동된 경우 1로 설정.
-        // 9 CONTROLLER RESET.   제어기 스스로 리셋한 경우 1로 설정.
-        //10-15 Reserved.
+        // 0 INVALID REQUEST                Host 로 부터 수신한 메시지의 내용이 비정상 적일 때 (비정상 시 : 1)
+        // 1 RESPONSE DATA NOT READY        Host 가 요청한 데이터가 준비되지 않은 경우 발생 (미준비 시 : 1)
+        // 2 UNKNOWN MESSAGE TYPE(OP-Cede)  OP-Code 의 내용이 비정상일 때 (비정상   시 : 1)
+        // 3 LONG POWER FAIL                2초를 초과한 시간 동안 Power Fail 이 발생한 경우 (fail 시 : 1)
+
+        // 4 SHORT POWER FAIL               2초 이하의 Power Fail 이 발생한 경우 (fail 시 : 1)
+        // 5 INVALID DATA FILED             (invalid 시 : 1)
+        // 6 기본 파라미터                  파라미터 Ram 이 기본값을   가지고 있어, Host 로부터 파라미터 Down-Load 가 필요한 경우 (download 필요한   경우 : 1)
+        // 7 전역 주소 수신                 Host 로부터 전역주소  ‘0xFFFFFFFF'를 수신한 경우 (전역주소를 수신했을 때 : 1),(단, 동기화 명령은 제외)
+
+        // 8 자동 SYNC                      Host 로 부터 Sync 명령을 받지 못한 경우, 일정시간 이후 (기본 1초) 제어기 스스로 동기화하는 경우 (auto sync 시 : 1)
+        // 9 앞문개방                       앞문이 개방된 경우 (개방시 : 1)
+        //10 뒷문개방                       뒷문이 개방된 경우 (개방시 : 1)
+        //11 Fan 작동                       펜이 작동하는 경우 (작동시 : 1)
+
+        //12 히터 작동                      히터가 작동하는 경우 (작동시 : 1)
+        //13 제어기 RESET                   제어기 스스로 Reset 한   경우 (reset 시 : 1)
+        //14 ACK (NORMAL = 0)               사용안함 (default=0)
+        //15 Video Input 여부 (NORMAL = 0)  영상검지기 제어기로 카메라 영상입력이 없을 때 : 1
 
         byte stts1 = packet.getHead().getStatus1();
         byte stts2 = packet.getHead().getStatus2();
 
-        /*
-        int LongPowerFail   = SysUtils.getBitValue(stts1, 0);      // 0       Long Power Fail. 2초를 초과한 시간 동안 POWER   FAIL 이 발생한 경우 1로 설정.
-        int ShortPowerFail  = SysUtils.getBitValue(stts1, 1);      // 1       Short Power Fail.2초 이하의 시간 동안 POWER FAIL 이   발생한 경우 1로 설정.
-        int Default         = SysUtils.getBitValue(stts1, 2);      // 2       Default Parameter. 파라미터 RAM 이 기본값을 가지고   있어, HOST 로부터 파라미터 다운로드가 필요한 경우 1로   설정.
-        int Broadcast       = SysUtils.getBitValue(stts1, 3);      // 3       Received   Broadcast Message(동기화 명령은 제외). HOST 로부터 전역주소 0xFFFFFFFF를 수신한 경우 1로 설정.
-        int AutoSynchronize = SysUtils.getBitValue(stts1, 4);      // 4       Auto Resynchronization. HOST 로부터 SYNC 명령을 받지 못한 경우, 일정시간 이후(기본1초) 제어기 스스로   동기화한 경우 1로 설정.
-        */
-        int FrontDoorOpen   = SysUtils.getBitValue(stts1, 5);      // 5       FRONT DOOR   OPENED. 앞문이 개방된 경우 1로   설정.
-        int BackDoorOpen    = SysUtils.getBitValue(stts1, 6);      // 6       REAR DOOR OPENED.   뒷문이 개방된 경우 1로 설정.
-        int Fan             = SysUtils.getBitValue(stts1, 7);      // 7       FAN OPERATED. 팬이 작동된 경우 1로 설정.
-
-        int Heater          = SysUtils.getBitValue(stts2, 0);      // 8       HEATER OPERATED. 히터가 작동된 경우 1로 설정.
-        //int Reset           = SysUtils.getBitValue(stts2, 1);      // 9       CONTROLLER RESET.   제어기 스스로 리셋한 경우 1로 설정.
+        int Invalid         = SysUtils.getBitValue(stts1, 0);
+        int Ready           = SysUtils.getBitValue(stts1, 1);
+
+        int FrontDoorOpen   = SysUtils.getBitValue(stts2, 1);
+        int BackDoorOpen    = SysUtils.getBitValue(stts2, 2);
+        int Fan             = SysUtils.getBitValue(stts2, 3);
+        int Heater          = SysUtils.getBitValue(stts2, 4);
+        int VideoInput      = SysUtils.getBitValue(stts2, 7);
+
+        log.error("I:{}, R:{}, FD:{}, BD:{}, F:{}, H:{}, V:{}", Invalid, Ready, FrontDoorOpen, BackDoorOpen, Fan, Heater, VideoInput);
 
         String CBOX_DOOR_STTS_CD  = (FrontDoorOpen == 0 && BackDoorOpen == 0) ? "CDS0" : "CDS1";
         String FRONT_DOOR_STTS_CD = FrontDoorOpen == 1 ? "CDS1" : "CDS0";
         String BACK_DOOR_STTS_CD  = BackDoorOpen  == 1 ? "CDS1" : "CDS0";
         String FAN_STTS_CD        = Fan           == 1 ? "PAS0" : "PAS1";
         String HETR_STTS_CD       = Heater        == 1 ? "HTS0" : "HTS1";
-        int    CBOX_TMPR	      = 0;
-        String VIDEO_INPUT	      = "VDI0";
+        String VIDEO_INPUT	      = VideoInput    == 1 ? "VDI1" : "VDI0";
 
         obj.getStts().setVDS_CTLR_NMBR(obj.getVDS_CTLR_NMBR());
         obj.getStts().setUPDT_DT(SysUtils.getSysTime());
@@ -217,12 +226,11 @@ public class VdsDataProcess {
         obj.getStts().setCBOX_DOOR_STTS_CD(CBOX_DOOR_STTS_CD);
         obj.getStts().setFAN_STTS_CD(FAN_STTS_CD);
         obj.getStts().setHETR_STTS_CD(HETR_STTS_CD);
-        // 함체온도 요청 프로토콜 추가로 여기에서 온도값 변경하면 안된다
-        //obj.getStts().setCBOX_TMPR(CBOX_TMPR);
         obj.getStts().setFRONT_DOOR_STTS_CD(FRONT_DOOR_STTS_CD);
         obj.getStts().setBACK_DOOR_STTS_CD(BACK_DOOR_STTS_CD);
         obj.getStts().setVIDEO_INPUT(VIDEO_INPUT);
 
+        //return (Invalid == 0 && Ready == 0);
         return true;
     }
 
@@ -235,10 +243,10 @@ public class VdsDataProcess {
             //add   => full -> wait
             //큐가 차더라도 바로 리턴함.
             if (!SERVER_DATA_QUEUE.offer(data)) {
-                log.error("TcpServerDataProcess-QueueFull: {}", Integer.valueOf(SERVER_DATA_QUEUE.size()));
+                log.error("VdsDataProcess-QueueFull: {}", SERVER_DATA_QUEUE.size());
             }
         } catch (Exception e) {
-            log.error("TcpServerDataProcess-QueueAddError: {}", e.getMessage(), e);
+            log.error("VdsDataProcess-QueueAddError: {}", e.getMessage(), e);
         }
     }
 

+ 1 - 0
src/main/java/com/its/vds/xnettcp/vds/protocol/VdsProtocol.java

@@ -48,6 +48,7 @@ public class VdsProtocol {
     public static final byte vds_STX    = (byte)0x02;
     public static final byte vds_ETX    = (byte)0x03;
 
+    public static final byte vds_Unknown            = (byte)0x00;   // Unknown
     public static final byte vds_Synchronization    = (byte)0x01;   // 제어기 동기화 (Syncronization) 제어기 동기화 #1[0x01] 센터→로컬 없음
     public static final byte vds_Reserved00         = (byte)0x02;   // VDS 데이터 요구 (Data Request) 장래사용 #2[0x02] - -
     public static final byte vds_Reserved01         = (byte)0x03;   // VDS 데이터 요구 (Data Request) 장래사용 #3[0x03] - -

+ 17 - 14
src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqFramePacket.java

@@ -2,12 +2,14 @@ package com.its.vds.xnettcp.vds.protocol;
 
 import com.google.common.primitives.Bytes;
 import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
 
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.ArrayList;
 import java.util.List;
 
+@Slf4j
 @Getter
 public class VdsReqFramePacket {
 
@@ -57,7 +59,7 @@ public class VdsReqFramePacket {
             bodySize = this.body.length;
         }
 
-        // HEAD
+        // HEAD (패킷 분석결과 DLE Stuffing 하지 않음)
         list.add(this.head.getDle());
         list.add(this.head.getStx());
 
@@ -68,13 +70,13 @@ public class VdsReqFramePacket {
             groupNo1 = (byte)((this.head.getGroupNo()      ) & 0xFF);
         }
         list.add(groupNo1);
-        if (groupNo1 == VdsProtocol.vds_DLE) {
-            list.add(groupNo1);
-        }
+//        if (groupNo1 == VdsProtocol.vds_DLE) {
+//            list.add(groupNo1);
+//        }
         list.add(groupNo2);
-        if (groupNo2 == VdsProtocol.vds_DLE) {
-            list.add(groupNo2);
-        }
+//        if (groupNo2 == VdsProtocol.vds_DLE) {
+//            list.add(groupNo2);
+//        }
 
         byte controllerNo1 = (byte)((this.head.getControllerNo() >> 8 ) & 0xFF);
         byte controllerNo2 = (byte)((this.head.getControllerNo()      ) & 0xFF);
@@ -83,13 +85,13 @@ public class VdsReqFramePacket {
             controllerNo1 = (byte)((this.head.getControllerNo()      ) & 0xFF);
         }
         list.add(controllerNo1);
-        if (controllerNo1 == VdsProtocol.vds_DLE) {
-            list.add(controllerNo1);
-        }
+//        if (controllerNo1 == VdsProtocol.vds_DLE) {
+//            list.add(controllerNo1);
+//        }
         list.add(controllerNo2);
-        if (controllerNo2 == VdsProtocol.vds_DLE) {
-            list.add(controllerNo2);
-        }
+//        if (controllerNo2 == VdsProtocol.vds_DLE) {
+//            list.add(controllerNo2);
+//        }
 
         list.add(this.head.getOpCode());
 
@@ -150,7 +152,8 @@ public class VdsReqFramePacket {
     }
 
     public void makeCRC() {
-        ByteBuffer byteBuffer = getByteBuffer();
+        // DLE Stuffing 이전 데이터에 대하여 CRC 수행
+        ByteBuffer byteBuffer = getBuffer();
         short crc = VdsProtocol.getCRC16ARC(byteBuffer.array(), 2, byteBuffer.array().length - 6);
         //byte crc1 = (byte)((crc >> 8) & 0xFF);
         //byte crc2 = (byte)((crc     ) & 0xFF);

+ 16 - 6
src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqImage.java

@@ -1,21 +1,31 @@
 package com.its.vds.xnettcp.vds.protocol;
 
+import java.nio.ByteOrder;
+
 /**
  * 화상이미지 요구
  */
 public class VdsReqImage extends VdsReqFramePacket {
 
-    private byte cameraNo;
-
     public VdsReqImage(short groupNo, short controllerNo) {
         super(groupNo, controllerNo, VdsProtocol.vds_Image);
-        this.body = new byte[1];
-        setCameraNo(0);
+        this.body = new byte[3];
+        setFrameNo(0);
+        setCameraNo(1);
     }
 
+    public void setFrameNo(int frameNo) {
+        short frameNo1 = (short) frameNo;
+        this.body[0] = (byte)((frameNo1 & 0xFF00) >> 8);
+        this.body[1] = (byte)((frameNo1 & 0x00FF));
+        if (VdsProtocol.byteOrder == ByteOrder.LITTLE_ENDIAN) {
+            this.body[1] = (byte)((frameNo1 >> 8 ) & 0xFF);
+            this.body[0] = (byte)((frameNo1) & 0xFF);
+        }
+    }
     public void setCameraNo(int cameraNo) {
         // 제어기에 연결된 카메라 번호(1~255)
-        this.cameraNo = (byte)(cameraNo & 0xFF);
-        this.body[0] = this.cameraNo;
+        byte cameraNo1 = (byte) (cameraNo & 0xFF);
+        this.body[2] = cameraNo1;
     }
 }

+ 2 - 3
src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqRTC.java

@@ -1,7 +1,6 @@
 package com.its.vds.xnettcp.vds.protocol;
 
 import com.its.app.utils.BcdConverter;
-import com.its.app.utils.SysUtils;
 
 /**
  * 개별차량 데이터 Request, 제어기에게 동기화 명령을 보낸 직후 개별차량 데이터 Request 명령 전송
@@ -9,11 +8,11 @@ import com.its.app.utils.SysUtils;
 public class VdsReqRTC extends VdsReqFramePacket {
 
     public VdsReqRTC(short groupNo, short controllerNo) {
-        super(groupNo, controllerNo, VdsProtocol.vds_Vehicle);
+        super(groupNo, controllerNo, VdsProtocol.vds_RTC);
         setRealTimeClock();
     }
 
     public void setRealTimeClock() {
-        this.body = BcdConverter.stringToBcd(SysUtils.getSysTime());
+        this.body = BcdConverter.stringToBcd("20220712100015");//SysUtils.getSysTime());
     }
 }

+ 16 - 1
src/main/java/com/its/vds/xnettcp/vds/protocol/VdsResFramePacket.java

@@ -1,5 +1,6 @@
 package com.its.vds.xnettcp.vds.protocol;
 
+import com.its.vds.entity.TbVdsCtlr;
 import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
 
@@ -12,11 +13,13 @@ public class VdsResFramePacket {
 
     private ByteOrder byteOrder = VdsProtocol.byteOrder;
 
+    TbVdsCtlr       vdsObj;
     VdsResFrameHead head;
     byte[]          body;
     VdsResFrameTail tail;
 
-    public VdsResFramePacket(byte[] packet, int size) {
+    public VdsResFramePacket(TbVdsCtlr obj, byte[] packet, int size) {
+        this.vdsObj = obj;
         if (packet != null) {
             // HEAD
             this.head = new VdsResFrameHead(packet);
@@ -37,6 +40,18 @@ public class VdsResFramePacket {
         }
     }
 
+    public String getObjectInfo() {
+        if (this.vdsObj != null) {
+            return this.vdsObj.getVDS_CTLR_ID() + ":" + this.vdsObj.getVDS_CTLR_IP();
+        }
+        return "???:???";
+    }
+    public byte getOpCode() {
+        if (this.head != null) {
+            return this.head.getOpCode();
+        }
+        return VdsProtocol.vds_Unknown;
+    }
     public void setByteOrder(ByteOrder byteOrder) {
         this.byteOrder = byteOrder;
     }

+ 1 - 1
src/main/resources/application.yml

@@ -80,7 +80,7 @@ spring:
     hikari:
       driver-class-name: com.tmax.tibero.jdbc.TbDriver
       #jdbc-url: jdbc:tibero:thin:@172.16.11.52:8800:new_yiitsdb
-      jdbc-url: jdbc:tibero:thin:@(DESCRIPTION=(FAILOVER=ON)(LOAD_BALANCE=ON)(ADDRESS_LIST=(ADDRESS=(HOST=172.16.11.52)(PORT=8800))(ADDRESS=(HOST=172.16.11.62)(PORT=8629)))(DATABASE_NAME=new_yiitsdb))
+      jdbc-url: jdbc:tibero:thin:@(DESCRIPTION=(FAILOVER=ON)(LOAD_BALANCE=ON)(ADDRESS_LIST=(ADDRESS=(HOST=172.16.11.52)(PORT=8800))(ADDRESS=(HOST=172.16.11.62)(PORT=8800)))(DATABASE_NAME=new_yiitsdb))
       username: yiits
       password: yiits
       minimumIdle: 5

+ 95 - 3
src/test/java/com/its/app/VdsCommServerApplicationTests.java

@@ -4,14 +4,19 @@ import com.google.common.primitives.Bytes;
 import com.its.app.utils.BcdConverter;
 import com.its.app.utils.SysUtils;
 import com.its.vds.VdsCommServerApplication;
-import com.its.vds.xnettcp.vds.protocol.VdsProtocol;
-import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import com.its.vds.entity.TbVdsCtlr;
+import com.its.vds.global.AppRepository;
+import com.its.vds.xnettcp.vds.process.VdsData;
+import com.its.vds.xnettcp.vds.process.VdsDataProcess;
+import com.its.vds.xnettcp.vds.protocol.*;
 import lombok.extern.slf4j.Slf4j;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
 
+import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 @Slf4j
 @SpringBootTest(classes = VdsCommServerApplication.class)
@@ -120,7 +125,7 @@ public class VdsCommServerApplicationTests {
                         totalMsgSize += msgSize;
                         log.error("OnePacket: {} Bytes, {} Bytes, {}", msgSize, totalMsgSize, SysUtils.byteArrayToHex(packets));
 
-                        VdsResFramePacket packet = new VdsResFramePacket(packets, msgSize);
+                        VdsResFramePacket packet = new VdsResFramePacket(null, packets, msgSize);
                         log.error("OnePacket: {} Bytes, {}", packet.getByteBuffer().array().length, SysUtils.byteArrayToHex(packet.getByteBuffer().array()));
                         break;
                     } else {
@@ -166,4 +171,91 @@ public class VdsCommServerApplicationTests {
         byte[] arr = Bytes.toArray(list);
         log.error("{}", SysUtils.byteArrayToHex(arr));
     }
+
+    @Test
+    void Test4() {
+        //10 02 00 00 00 1C 04 10 03 03 09
+        byte[] packet = { (byte)0x10, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x1C, (byte)0x04, (byte)0x10, (byte)0x03, (byte)0x00, (byte)0x00};
+        short crc = VdsProtocol.getCRC16ARC(packet, 2, packet.length - 6);
+
+        // 제어기 통과 데이터 요청
+        for (Map.Entry<String, TbVdsCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
+            TbVdsCtlr obj = e.getValue();
+            ByteBuffer sendBuffer = obj.getReqData().getByteBuffer();
+            //log.error("{}: {}", obj.getVDS_CTLR_LOCAL_NO(), SysUtils.byteArrayToHex(sendBuffer.array()));
+        }
+
+        // 제어기 SYC
+        for (Map.Entry<String, TbVdsCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
+            TbVdsCtlr obj = e.getValue();
+            ByteBuffer sendBuffer = obj.getReqSynchronize().getByteBuffer();
+            //log.error("{}: {}", obj.getVDS_CTLR_LOCAL_NO(), SysUtils.byteArrayToHex(sendBuffer.array()));
+        }
+
+        // 제어기 온도 데이터 요청
+        for (Map.Entry<String, TbVdsCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
+            TbVdsCtlr obj = e.getValue();
+            ByteBuffer sendBuffer = obj.getReqTemperature().getByteBuffer();
+            //log.error("{}: {}", obj.getVDS_CTLR_LOCAL_NO(), SysUtils.byteArrayToHex(sendBuffer.array()));
+        }
+
+        // 제어기 상태 RTC 변경
+        for (Map.Entry<String, TbVdsCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
+            TbVdsCtlr obj = e.getValue();
+            VdsReqRTC reqRTC = new VdsReqRTC((short)obj.getGROUP_NO(), (short)obj.getVDS_CTLR_LOCAL_NO());
+            reqRTC.makeCRC();
+            ByteBuffer sendBuffer = reqRTC.getByteBuffer();
+            //log.error("{}: {}", obj.getVDS_CTLR_LOCAL_NO(), SysUtils.byteArrayToHex(sendBuffer.array()));
+        }
+
+        // 화상 이미지 요청
+        for (int ii = 0; ii < 13; ii++) {
+            VdsReqImage reqImage = new VdsReqImage((short)0, (short)2);
+            reqImage.setCameraNo(1);
+            reqImage.setFrameNo(ii);
+            reqImage.makeCRC();
+            ByteBuffer sendBuffer = reqImage.getByteBuffer();
+            //log.error("{}, {}: {}", 2, ii, SysUtils.byteArrayToHex(sendBuffer.array()));
+        }
+
+        // 제어기 RESET
+        for (Map.Entry<String, TbVdsCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
+            TbVdsCtlr obj = e.getValue();
+            VdsReqReset reqReset = new VdsReqReset((short)obj.getGROUP_NO(), (short)obj.getVDS_CTLR_LOCAL_NO());
+            reqReset.makeCRC();
+            ByteBuffer sendBuffer = reqReset.getByteBuffer();
+            log.error("{}: {}", obj.getVDS_CTLR_LOCAL_NO(), SysUtils.byteArrayToHex(sendBuffer.array()));
+        }
+    }
+
+    @Test
+    void Test5() {
+        // 온도 수신
+        byte[] recvBytes = { (byte)0x10, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x12, (byte)0x1E,
+                (byte)0x8A, (byte)0x40, (byte)0x21, (byte)0x00, (byte)0xDF, (byte)0x10, (byte)0x03, (byte)0xF2, (byte)0xB9};
+        //(byte)0x8A, (byte)0x00, (byte)0x21, (byte)0x00, (byte)0xDF, (byte)0x10, (byte)0x03, (byte)0xF2, (byte)0xB9};
+        VdsDataProcess vdsDataProcess = (VdsDataProcess)AppUtils.getBean(VdsDataProcess.class);
+        TbVdsCtlr obj = AppRepository.getInstance().getCtlrMap().get("00000018");
+        VdsResFramePacket packet = new VdsResFramePacket(obj, recvBytes, recvBytes.length);
+        vdsDataProcess.add(new VdsData(obj, obj.getVDS_CTLR_IP(), null, packet));
+
+        VdsProtocol.sleep(6000);
+    }
+    //[2022-07-12 09:59:44] [22번 제어기 교통정보응답 수신] 10 02 00 00 00 16 04 88 40 01 00 00 00 00 00 00 00 00 00 00 00 00 00 0B 27 1A 61 3E 03 05 46 5A 08 32 0F 5D 40 04 03 29 47 06 35 0B 11 3F 03 02 25 42 10 03 E9 54
+
+    @Test
+    void Test6() {
+        // 교통정보응답수신(22번 제어기)
+        //byte[] recvBytes = { (byte)0x10, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x16, (byte)0x04, (byte)0x88, (byte)0x40, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0B, (byte)0x27, (byte)0x1A, (byte)0x61, (byte)0x3E, (byte)0x03, (byte)0x05, (byte)0x46, (byte)0x5A, (byte)0x08, (byte)0x32, (byte)0x0F, (byte)0x5D, (byte)0x40, (byte)0x04, (byte)0x03, (byte)0x29, (byte)0x47, (byte)0x06, (byte)0x35, (byte)0x0B, (byte)0x11, (byte)0x3F, (byte)0x03, (byte)0x02, (byte)0x25, (byte)0x42, (byte)0x10, (byte)0x03, (byte)0xE9, (byte)0x54};
+        // 교통정보응답수신(15번 제어기)
+        byte[] recvBytes = {(byte)0x10, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0F, (byte)0x04, (byte)0x8A, (byte)0x40, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x07, (byte)0x5E, (byte)0x05, (byte)0x48, (byte)0x2E, (byte)0x04, (byte)0x01, (byte)0x0E, (byte)0x26, (byte)0x0C, (byte)0x4B, (byte)0x0E, (byte)0x02, (byte)0x36, (byte)0x02, (byte)0x02, (byte)0x5D, (byte)0x2F, (byte)0x05, (byte)0x45, (byte)0x07, (byte)0x03, (byte)0x3C, (byte)0x06, (byte)0x01, (byte)0x2D, (byte)0x33, (byte)0x02, (byte)0x47, (byte)0x04, (byte)0x16, (byte)0x69, (byte)0x0A, (byte)0x00, (byte)0x62, (byte)0x32, (byte)0x07, (byte)0x40, (byte)0x0C, (byte)0x57, (byte)0x44, (byte)0x04, (byte)0x02, (byte)0x30, (byte)0x37, (byte)0x03, (byte)0x3C, (byte)0x06, (byte)0x41, (byte)0x5B, (byte)0x07, (byte)0x01, (byte)0x33, (byte)0x3B, (byte)0x10, (byte)0x03, (byte)0xB5, (byte)0x2C};
+        //(byte)0x8A, (byte)0x00, (byte)0x21, (byte)0x00, (byte)0xDF, (byte)0x10, (byte)0x03, (byte)0xF2, (byte)0xB9};
+        VdsDataProcess vdsDataProcess = (VdsDataProcess)AppUtils.getBean(VdsDataProcess.class);
+        TbVdsCtlr obj = AppRepository.getInstance().getCtlrMap().get("00000015");
+        VdsResFramePacket packet = new VdsResFramePacket(obj, recvBytes, recvBytes.length);
+        vdsDataProcess.add(new VdsData(obj, obj.getVDS_CTLR_IP(), null, packet));
+
+        VdsProtocol.sleep(6000);
+    }
+
 }