shjung 3 år sedan
förälder
incheckning
20cca7d132
23 ändrade filer med 457 tillägg och 173 borttagningar
  1. 1 0
      conf/vds-comm-server.pid
  2. 1 1
      src/main/java/com/its/vds/VdsCommServerApplication.java
  3. 3 3
      src/main/java/com/its/vds/config/ControllerCommConfig.java
  4. 36 9
      src/main/java/com/its/vds/entity/TbVdsCtlr.java
  5. 17 20
      src/main/java/com/its/vds/service/VdsCtlrService.java
  6. 87 1
      src/main/java/com/its/vds/xnettcp/center/codec/CenterTcpServerDecoder.java
  7. 24 1
      src/main/java/com/its/vds/xnettcp/center/codec/CenterTcpServerEncoder.java
  8. 14 0
      src/main/java/com/its/vds/xnettcp/center/handler/CenterTcpServerIdleStateHandler.java
  9. 64 5
      src/main/java/com/its/vds/xnettcp/center/handler/CenterTcpServerInboundHandler.java
  10. 3 0
      src/main/java/com/its/vds/xnettcp/center/initializer/CenterTcpServerInitializer.java
  11. 10 0
      src/main/java/com/its/vds/xnettcp/center/protocol/CenterProtocol.java
  12. 16 26
      src/main/java/com/its/vds/xnettcp/center/protocol/CenterReqFrameHead.java
  13. 23 0
      src/main/java/com/its/vds/xnettcp/center/protocol/CenterReqFramePacket.java
  14. 43 0
      src/main/java/com/its/vds/xnettcp/center/protocol/CenterResProtocol.java
  15. 2 2
      src/main/java/com/its/vds/xnettcp/vds/VdsTcpClient.java
  16. 16 20
      src/main/java/com/its/vds/xnettcp/vds/VdsTcpClientBootstrapFactory.java
  17. 2 2
      src/main/java/com/its/vds/xnettcp/vds/VdsTcpClientCommService.java
  18. 58 59
      src/main/java/com/its/vds/xnettcp/vds/codec/VdsTcpClientDecoder.java
  19. 32 19
      src/main/java/com/its/vds/xnettcp/vds/process/Job_Image.java
  20. 2 2
      src/main/java/com/its/vds/xnettcp/vds/process/VdsDataProcess.java
  21. 1 1
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsResFramePacket.java
  22. 1 1
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsResFrameTail.java
  23. 1 1
      src/main/resources/application.yml

+ 1 - 0
conf/vds-comm-server.pid

@@ -0,0 +1 @@
+16640

+ 1 - 1
src/main/java/com/its/vds/VdsCommServerApplication.java

@@ -79,7 +79,7 @@ public class VdsCommServerApplication implements CommandLineRunner, ApplicationL
         ctlrService.updateCtlrStts(true);
 
         VdsTcpClientCommService vdsCommClientService = (VdsTcpClientCommService)AppUtils.getBean(VdsTcpClientCommService.class);
-        //vdsCommClientService.run();
+        vdsCommClientService.run();
 
         CenterTcpServerService centerService = (CenterTcpServerService)AppUtils.getBean(CenterTcpServerService.class);
         centerService.run();

+ 3 - 3
src/main/java/com/its/vds/config/LocalCommConfig.java → src/main/java/com/its/vds/config/ControllerCommConfig.java

@@ -14,13 +14,13 @@ import javax.annotation.PostConstruct;
 @Setter
 @ToString
 @Configuration
-@ConfigurationProperties(prefix = "application.local-comm")
-public class LocalCommConfig {
+@ConfigurationProperties(prefix = "application.controller-comm")
+public class ControllerCommConfig {
 
     private boolean commLogging = false;
     private int retrySeconds = 10;
     private int connectTimeout = 5;
-    private int readerIdleTime = 10;
+    private int readerIdleTime = 0;
     private int writerIdleTime = 0;
     private int allIdleTime = 0;
 

+ 36 - 9
src/main/java/com/its/vds/entity/TbVdsCtlr.java

@@ -65,6 +65,27 @@ public class TbVdsCtlr {
 	private int frameNo;
 	private int cameraNo;
 	private int imageSize;
+	private ByteBuffer imageBuffer;
+
+	public void addImageData(byte[] imageData) {
+		if (imageData == null) {
+			return;
+		}
+
+		if (this.imageBuffer == null) {
+			this.imageBuffer = ByteBuffer.wrap(imageData);
+			imageBuffer.order(VdsProtocol.byteOrder);
+		}
+		else {
+			byte[] prevImage = this.imageBuffer.array();
+			this.imageBuffer = ByteBuffer.allocate(prevImage.length + imageData.length);
+			this.imageBuffer.put(prevImage);
+			this.imageBuffer.put(imageData);
+		}
+	}
+	public ByteBuffer getImageData() {
+		return this.imageBuffer;
+	}
 	public void addImageSize(int imageSize) {
 		this.imageSize += imageSize;
 	}
@@ -87,18 +108,24 @@ public class TbVdsCtlr {
 		if (!this.requestStopImage) {
 			this.requestImageList.clear();
 			this.requestImageList = new ArrayList<>();
-			this.cameraNo = cameraNo;
-			this.frameNo = frameNo;
-			this.imageSize = 0;
+			//this.cameraNo = cameraNo;
+			//this.frameNo = frameNo;
+			//this.imageSize = 0;
 		}
+		// 마지막 요청을 유지하자
+		this.imageBuffer = null;
+		this.imageSize = 0;
+		this.cameraNo = cameraNo;
+		this.frameNo = frameNo;
 		this.requestImageList.add(channel);
 		this.requestStopImage = true;
 	}
 	public void setStopImageResponse() {
+		this.imageBuffer = null;
+		this.imageSize = 0;
 		this.requestStopImage = false;
 		this.cameraNo = 0;
 		this.frameNo = 0;
-		this.imageSize = 0;
 	}
 
 	public TbVdsCtlr() {
@@ -190,24 +217,24 @@ public class TbVdsCtlr {
 
 	/**
 	 * Channel Send Data
-	 * @param sendBuff
+	 * @param sendBuffer
 	 * @param delayMilliSeconds
 	 * @param packetDesc
 	 * @return
 	 */
-	public boolean sendData(ByteBuffer sendBuff, int delayMilliSeconds, String packetDesc) {
+	public boolean sendData(ByteBuffer sendBuffer, int delayMilliSeconds, String packetDesc) {
 		boolean result = false;
 		if (this.channel != null) {
-			ChannelFuture f = this.channel.writeAndFlush(sendBuff);
+			ChannelFuture f = this.channel.writeAndFlush(sendBuffer);
 			f.awaitUninterruptibly();
 			if (f.isDone() || f.isSuccess()) {
 				result = true;
-				log.info("SEND_0: [{}], {}: {} sendBytes. [{}]", this.VDS_CTLR_IP, packetDesc, sendBuff.array().length, this.VDS_CTLR_ID);
+				log.info("SEND_0: [{}], {}: {} sendBytes. [{}]", this.VDS_CTLR_IP, packetDesc, sendBuffer.array().length, this.VDS_CTLR_ID);
 				if (delayMilliSeconds > 0) {
 					VdsProtocol.sleep(delayMilliSeconds);
 				}
 			} else {
-				log.error("SEND_0: [{}], {}: {} sendBytes, Failed. [{}]", this.VDS_CTLR_IP, packetDesc, sendBuff.array().length, this.VDS_CTLR_ID);
+				log.error("SEND_0: [{}], {}: {} sendBytes, Failed. [{}]", this.VDS_CTLR_IP, packetDesc, sendBuffer.array().length, this.VDS_CTLR_ID);
 			}
 		}
 		return result;

+ 17 - 20
src/main/java/com/its/vds/service/VdsCtlrService.java

@@ -12,11 +12,8 @@ import com.its.vds.global.AppRepository;
 import com.its.vds.process.DbmsJobData;
 import com.its.vds.process.DbmsJobProcess;
 import com.its.vds.process.DbmsJobType;
-import com.its.vds.xnetudp.protocol.CENTER_COMM_DEFINE;
-import com.its.vds.xnetudp.protocol.CENTER_PG_STATE_RES;
 import com.its.vds.xnetudp.protocol.CENTER_VDS_RES_STATE;
 import com.its.vds.xnetudp.protocol.voVdsState;
-import com.its.vds.xnetudp.thread.CenterCommClientSender;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
 import org.springframework.stereotype.Service;
@@ -216,23 +213,23 @@ public class VdsCtlrService {
         stts.setNormal((short)normal);
         stts.setModule((short)0);
 
-        // 제어기 상태정보 운영단말 전송
-        CenterCommClientSender notify = (CenterCommClientSender) AppUtils.getBean(CenterCommClientSender.class);
-        notify.run(null, 0, stts.getBuffer());
-
-        // 프로세스 상태정보 운영단말 전송
-        byte db = CENTER_PG_STATE_RES.STATE_ERROR;
-        byte comm = error > 0 ? CENTER_PG_STATE_RES.STATE_ERROR : CENTER_PG_STATE_RES.STATE_NORMAL;
-        byte action = CENTER_PG_STATE_RES.STATE_NORMAL;
-        if (!isRun) {
-            db = CENTER_PG_STATE_RES.STATE_ERROR;
-            comm = CENTER_PG_STATE_RES.STATE_ERROR;
-            action = CENTER_PG_STATE_RES.STATE_ERROR;
-        }
-
-        // 프로그램 상태정보 운영단말 전송
-        CENTER_PG_STATE_RES pgStts = new CENTER_PG_STATE_RES(CENTER_COMM_DEFINE.INT_ID_VDS_SERVER, db, comm, action);
-        notify.run(null, 0, pgStts.getBuffer());
+//        // 제어기 상태정보 운영단말 전송
+//        CenterCommClientSender notify = (CenterCommClientSender) AppUtils.getBean(CenterCommClientSender.class);
+//        notify.run(null, 0, stts.getBuffer());
+//
+//        // 프로세스 상태정보 운영단말 전송
+//        byte db = CENTER_PG_STATE_RES.STATE_ERROR;
+//        byte comm = error > 0 ? CENTER_PG_STATE_RES.STATE_ERROR : CENTER_PG_STATE_RES.STATE_NORMAL;
+//        byte action = CENTER_PG_STATE_RES.STATE_NORMAL;
+//        if (!isRun) {
+//            db = CENTER_PG_STATE_RES.STATE_ERROR;
+//            comm = CENTER_PG_STATE_RES.STATE_ERROR;
+//            action = CENTER_PG_STATE_RES.STATE_ERROR;
+//        }
+//
+//        // 프로그램 상태정보 운영단말 전송
+//        CENTER_PG_STATE_RES pgStts = new CENTER_PG_STATE_RES(CENTER_COMM_DEFINE.INT_ID_VDS_SERVER, db, comm, action);
+//        notify.run(null, 0, pgStts.getBuffer());
 
         log.info("VdsCtlrService.updateCtlrStts: total {}, normal {}, error {}", normal + error, normal, error);
     }

+ 87 - 1
src/main/java/com/its/vds/xnettcp/center/codec/CenterTcpServerDecoder.java

@@ -1,6 +1,12 @@
 package com.its.vds.xnettcp.center.codec;
 
+import com.its.app.utils.NettyUtils;
+import com.its.vds.xnettcp.center.handler.CenterTcpServerIdleStateHandler;
+import com.its.vds.xnettcp.center.protocol.CenterProtocol;
+import com.its.vds.xnettcp.center.protocol.CenterReqFrameHead;
+import com.its.vds.xnettcp.center.protocol.CenterReqFramePacket;
 import io.netty.buffer.ByteBuf;
+import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.ByteToMessageDecoder;
 import lombok.extern.slf4j.Slf4j;
@@ -11,7 +17,87 @@ import java.util.List;
 public class CenterTcpServerDecoder extends ByteToMessageDecoder {
 
     @Override
-    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+    protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception {
+        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());
+        Channel channel = ctx.channel();
+        try {
+            if (!channel.isOpen() || !channel.isActive()) {
+                log.error("CenterTcpServerDecoder.decode: {}, isOpen: {}, isActive: {}", ipAddress, channel.isOpen(), channel.isActive());
+                CenterTcpServerIdleStateHandler.disconnectChannel(channel);
+                return;
+            }
 
+            int readableBytes = byteBuf.readableBytes();
+            log.info("CENTER_RECV_0: [{}]. ReadableBytes: {} Bytes, ReaderIndex: {}", ipAddress, readableBytes, byteBuf.readerIndex());
+            if (readableBytes == 0) {
+                log.error("CENTER_RECV_0: {}. byteBuf.readableBytes() == 0.", ipAddress);
+                return;
+            }
+
+            int packetCnt = 0;
+            int headLength = CenterProtocol.HEADER_SIZE;
+            int bodyLength = 0;
+            int remainLength = 0;
+            while (readableBytes >= headLength) {
+                byteBuf.markReaderIndex();
+                byte[] headBuffer = new byte[headLength];
+                byteBuf.readBytes(headBuffer);
+
+                // 헤더 데이터 먼저 읽는다.
+                CenterReqFrameHead head = new CenterReqFrameHead(headBuffer);
+                bodyLength = head.getLength();
+                remainLength = readableBytes - headLength;
+                if (head.getSender() != (byte)0x24) {
+                    log.error("CenterTcpServerDecoder.decode: {}, Sender Error: {}", ipAddress, head.getSender());
+                    CenterTcpServerIdleStateHandler.disconnectChannel(channel);
+                    return;
+                }
+                if (head.getReceiver() != (byte)0x04) {
+                    log.error("CenterTcpServerDecoder.decode: {}, Receiver Error: {}", ipAddress, head.getReceiver());
+                    CenterTcpServerIdleStateHandler.disconnectChannel(channel);
+                    return;
+                }
+
+                if (bodyLength > remainLength) {
+                    // 패킷을 한번에 수신하지 못하였다.
+                    log.warn("CENTER_RECV_0: [{}]. ReadableBytes: {} Bytes, ReaderIndex: {}, The packet was not completed. Body/Remain: {}/{}.",
+                            ipAddress, readableBytes, byteBuf.readerIndex(), bodyLength, remainLength);
+                    break;
+                }
+                if (bodyLength == 0) {
+                    // body length 는 항상 0보다 커야 정상적인 패킷이다.
+                    // 현재 읽어들인 데이터를 모두 버려버리자.
+                    byteBuf.readerIndex(byteBuf.readerIndex());
+                    byteBuf.markReaderIndex();
+                    byteBuf.discardReadBytes();
+                    break;
+                }
+
+                // 버퍼를 헤더 크기만큼 이동
+                byteBuf.readerIndex(headLength);
+                byteBuf.markReaderIndex();
+                byteBuf.discardReadBytes();
+
+                // Body 데이터를 읽어 들인다.
+                byte[] bodyBuffer = new byte[bodyLength];
+                byteBuf.readBytes(bodyBuffer);
+
+                // 버퍼를 Body 크기만큼 이동
+                byteBuf.readerIndex(bodyLength);
+                byteBuf.markReaderIndex();
+                byteBuf.discardReadBytes();
+
+                // 한 패킷이 완성되었음.
+                CenterReqFramePacket body = new CenterReqFramePacket(head, bodyBuffer);
+                out.add(body);
+
+                readableBytes = byteBuf.readableBytes();
+                packetCnt++;
+                log.info("CENTER_RECV_{}: [{}]. ReadableBytes: {} Bytes, ReaderIndex: {}, ===> packet encoding ok.", packetCnt, ipAddress, readableBytes, byteBuf.readerIndex());
+            }
+        }
+        finally {
+            byteBuf.resetReaderIndex();
+        }
     }
 }

+ 24 - 1
src/main/java/com/its/vds/xnettcp/center/codec/CenterTcpServerEncoder.java

@@ -1,12 +1,17 @@
 package com.its.vds.xnettcp.center.codec;
 
+import com.its.app.utils.NettyUtils;
+import com.its.vds.xnettcp.center.handler.CenterTcpServerIdleStateHandler;
 import io.netty.buffer.ByteBuf;
+import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.MessageToByteEncoder;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 
+import java.nio.ByteBuffer;
+
 @Slf4j
 @Component
 @ChannelHandler.Sharable
@@ -15,5 +20,23 @@ public class CenterTcpServerEncoder extends MessageToByteEncoder<Object> {
     @Override
     protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
 
-    }
+        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());
+        Channel channel = ctx.channel();
+
+        if (!channel.isOpen() || !channel.isActive()) {
+            log.error("CenterTcpServerEncoder.encode: {}, isOpen: {}, isActive: {}.", ipAddress, channel.isOpen(), channel.isActive());
+            CenterTcpServerIdleStateHandler.disconnectChannel(channel);
+            return;
+        }
+
+        if (!(msg instanceof ByteBuffer)) {
+            log.error("CenterTcpServerEncoder.encode: {}, msg is not ByteBuffer.", ipAddress);
+            CenterTcpServerIdleStateHandler.disconnectChannel(channel);
+            return;
+        }
+
+        ByteBuffer buffer = (ByteBuffer)msg;
+        byte[] sendBytes = buffer.array();
+        out.writeBytes(sendBytes);
+     }
 }

+ 14 - 0
src/main/java/com/its/vds/xnettcp/center/handler/CenterTcpServerIdleStateHandler.java

@@ -2,6 +2,7 @@ package com.its.vds.xnettcp.center.handler;
 
 import com.its.app.utils.NettyUtils;
 import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.timeout.IdleStateHandler;
@@ -52,6 +53,19 @@ public class CenterTcpServerIdleStateHandler extends IdleStateHandler {
         String ipAddress = NettyUtils.getRemoteIpAddress(channel);
         int port = NettyUtils.getRemotePort(channel);
         log.info("disconnectChannel: {}", NettyUtils.getRemoteAddress(channel));
+        //////////////////////////////////
+        // 클라이언트와의 연결을 종료한다.
+        //////////////////////////////////
+        if (!channel.isActive()) {
+            log.error("disconnectChannel: [{}], channel already closed.", ipAddress);
+            return;
+        }
+
+        channel.flush();
+        ChannelFuture f = channel.disconnect().awaitUninterruptibly();
+        if (!f.isDone() || !f.isSuccess()) {
+            log.error("disconnectChannel: [{}], isDone: {}, isSuccess: {}", ipAddress, f.isDone(), f.isSuccess());
+        }
     }
 
 }

+ 64 - 5
src/main/java/com/its/vds/xnettcp/center/handler/CenterTcpServerInboundHandler.java

@@ -1,13 +1,23 @@
 package com.its.vds.xnettcp.center.handler;
 
 import com.its.app.utils.NettyUtils;
-import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
+import com.its.vds.domain.NET;
+import com.its.vds.entity.TbVdsCtlr;
+import com.its.vds.global.AppRepository;
+import com.its.vds.xnettcp.center.protocol.CenterReqFramePacket;
+import com.its.vds.xnettcp.vds.protocol.VdsProtocol;
+import com.its.vds.xnettcp.vds.protocol.VdsReqFrameHead;
+import com.its.vds.xnettcp.vds.protocol.VdsReqImage;
+import com.its.vds.xnettcp.vds.protocol.VdsReqReset;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 
+import java.nio.ByteBuffer;
+import java.util.Map;
+
 @Slf4j
 @Component
 @ChannelHandler.Sharable
@@ -16,13 +26,62 @@ public class CenterTcpServerInboundHandler extends ChannelInboundHandlerAdapter
     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()));
+        if (!(msg instanceof CenterReqFramePacket)) {
+            log.error("[{}] | Received Data is not CenterReqFramePacket Object", NettyUtils.getRemoteIpAddress(ctx.channel()));
+            return;
+        }
+        CenterReqFramePacket centerReqHead = (CenterReqFramePacket)msg;
+        VdsReqFrameHead vdsReqHead = new VdsReqFrameHead(centerReqHead.getBody());
+        short groupNo = vdsReqHead.getGroupNo();
+        short ctlrNo = vdsReqHead.getControllerNo();
+        byte opCode = vdsReqHead.getOpCode();
+
+        TbVdsCtlr obj = null;
+        for (Map.Entry<String, TbVdsCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
+            TbVdsCtlr tmp = e.getValue();
+            if (tmp.getVDS_CTLR_LOCAL_NO() == ctlrNo) {
+                obj = tmp;
+                break;
+            }
+        }
+        if (obj == null) {
+            log.error("CenterTcpServerInboundHandler: Center Request Unknown VDS: [{}]", ctlrNo);
             return;
         }
+        if (obj.getChannel() == null || obj.getNetState() == NET.CLOSED) {
+            log.error("CenterTcpServerInboundHandler: Center Request VDS Not Connect: [{}]", obj);
+            //return;
+        }
 
-//        VdsResFramePacket resFramePacket = (VdsResFramePacket)msg;
-//        this.vdsDataProcess.add(new VdsData(resFramePacket.getVdsObj(), ipAddress, ctx, resFramePacket));
+        if (opCode == VdsProtocol.vds_Reset) {
+            VdsReqReset reqReset = new VdsReqReset((short)obj.getGROUP_NO(), (short)obj.getVDS_CTLR_LOCAL_NO());
+            reqReset.makeCRC();
+            ByteBuffer sendBuffer = reqReset.getByteBuffer();
+            if (!obj.sendData(sendBuffer, 0, "vds_Reset")) {
+                log.error("CenterTcpServerInboundHandler: Center Request VDS Reset Data Send Failed: [{}]", obj);
+            }
+        }
+        else if (opCode == VdsProtocol.vds_Image) {
+            int frameNo = 0;    // first image request
+            byte cameraNo = centerReqHead.getBody()[9];
+            if (cameraNo == 0x00) {
+                cameraNo = 0x01;
+            }
+            obj.setStopImageRequest(ctx.channel(), cameraNo, frameNo);
+            VdsReqImage reqImage = new VdsReqImage((short)obj.getGROUP_NO(), (short)obj.getVDS_CTLR_LOCAL_NO());
+            reqImage.setCameraNo(cameraNo);
+            reqImage.setFrameNo(frameNo);
+            reqImage.makeCRC();
+            ByteBuffer sendBuffer = reqImage.getByteBuffer();
+            if (!obj.sendData(sendBuffer, 0, "vds_Image")) {
+                obj.setStopImageResponse();
+                log.error("CenterTcpServerInboundHandler: Center Request VDS Image Data Send Failed: [{}]", obj);
+            }
+        }
+        else {
+            log.error("CenterTcpServerInboundHandler: Center Request Not Support: [{}]", opCode);
+            return;
+        }
     }
 
 }

+ 3 - 0
src/main/java/com/its/vds/xnettcp/center/initializer/CenterTcpServerInitializer.java

@@ -7,6 +7,8 @@ import com.its.vds.xnettcp.center.handler.CenterTcpServerInboundHandler;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelInitializer;
 import io.netty.channel.ChannelPipeline;
+import io.netty.handler.logging.LogLevel;
+import io.netty.handler.logging.LoggingHandler;
 import lombok.RequiredArgsConstructor;
 
 @RequiredArgsConstructor
@@ -19,6 +21,7 @@ public class CenterTcpServerInitializer extends ChannelInitializer<Channel> {
     protected void initChannel(Channel channel) throws Exception {
         CenterTcpServerIdleStateHandler idleStateHandler = new CenterTcpServerIdleStateHandler(0, 0, 0);
         ChannelPipeline pipeline = channel.pipeline();
+        pipeline.addLast(new LoggingHandler(LogLevel.WARN));
         pipeline.addLast("centerServerIdleStateHandler", idleStateHandler);
         pipeline.addLast("centerServerDecoder", new CenterTcpServerDecoder());
         pipeline.addLast("centerServerInboundHandler", this.centerTcpServerInboundHandler);

+ 10 - 0
src/main/java/com/its/vds/xnettcp/center/protocol/CenterProtocol.java

@@ -0,0 +1,10 @@
+package com.its.vds.xnettcp.center.protocol;
+
+import java.nio.ByteOrder;
+
+public class CenterProtocol {
+
+    public static final ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;
+    public static final int HEADER_SIZE = 10;
+
+}

+ 16 - 26
src/main/java/com/its/vds/xnettcp/center/protocol/CenterReqFrameHead.java

@@ -1,6 +1,5 @@
 package com.its.vds.xnettcp.center.protocol;
 
-import com.its.vds.xnettcp.vds.protocol.VdsProtocol;
 import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
 
@@ -10,40 +9,31 @@ import java.nio.ByteBuffer;
 @Getter
 public class CenterReqFrameHead {
 
-    public static int SIZE = 7;
+    public static int SIZE = 10;
     public static int OPCODE_POS = 6;
 
-    private final byte dle = VdsProtocol.vds_DLE;
-    private final byte stx = VdsProtocol.vds_STX;
-
-    private short groupNo;
-    private short controllerNo;
-    private byte  opCode;
-
-    public CenterReqFrameHead() {
-        this.groupNo = 0;
-        this.controllerNo = 0;
-        this.opCode = 0;
-    }
-
-    public CenterReqFrameHead(short groupNo, short controllerNo, byte opCode) {
-        this.groupNo = groupNo;
-        this.controllerNo = controllerNo;
-        this.opCode = opCode;
-    }
+    private byte sender;
+    private byte receiver;
+    private byte total;
+    private byte current;
+    private byte reserved;
+    private byte opCode;
+    private int  length;
 
     public CenterReqFrameHead(byte[] headBytes) {
         if (headBytes != null && headBytes.length >= SIZE) {
             ByteBuffer byteBuffer = ByteBuffer.wrap(headBytes);
-            byteBuffer.order(VdsProtocol.byteOrder);
-            byte dle = byteBuffer.get();
-            byte stx = byteBuffer.get();
-            this.groupNo = byteBuffer.getShort();
-            this.controllerNo = byteBuffer.getShort();
+            byteBuffer.order(CenterProtocol.byteOrder);
+            this.sender = byteBuffer.get();
+            this.receiver = byteBuffer.get();
+            this.total = byteBuffer.get();
+            this.current = byteBuffer.get();
+            this.reserved = byteBuffer.get();
             this.opCode = byteBuffer.get();
+            this.length = byteBuffer.getInt();
         }
         else {
-            log.error("VdsReqFrameHead: create failed, headBytes error");
+            log.error("CenterReqFrameHead: create failed, headBytes error");
         }
     }
 

+ 23 - 0
src/main/java/com/its/vds/xnettcp/center/protocol/CenterReqFramePacket.java

@@ -0,0 +1,23 @@
+package com.its.vds.xnettcp.center.protocol;
+
+import com.its.vds.xnettcp.vds.protocol.VdsProtocol;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.nio.ByteOrder;
+
+@Slf4j
+@Getter
+public class CenterReqFramePacket {
+
+    private ByteOrder byteOrder = VdsProtocol.byteOrder;
+
+    protected CenterReqFrameHead head;
+    protected byte[]             body;
+
+    public CenterReqFramePacket(CenterReqFrameHead head, byte[] body) {
+        this.head = head;
+        this.body = body;
+    }
+
+}

+ 43 - 0
src/main/java/com/its/vds/xnettcp/center/protocol/CenterResProtocol.java

@@ -0,0 +1,43 @@
+package com.its.vds.xnettcp.center.protocol;
+
+import com.its.vds.xnettcp.vds.protocol.VdsProtocol;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public class CenterResProtocol {
+
+    public static ByteBuffer getImageHeader1() {
+        ByteBuffer byteBuffer = ByteBuffer.allocate(10);
+        byteBuffer.order(ByteOrder.BIG_ENDIAN);
+        byteBuffer.put((byte)0x00); // 송신시스템-운영단말
+        byteBuffer.put((byte)0x00); // 수신시스템-VDS 서버
+        byteBuffer.put((byte)0x00); // 전체프레임개수
+        byteBuffer.put((byte)0x00); // 현재프레임번호
+        byteBuffer.put((byte)0x00); // Reserved
+        byteBuffer.put(VdsProtocol.vds_Image);     // OP Code
+        byteBuffer.putInt(0);  // 데이터 길이
+
+        return byteBuffer;
+    }
+
+    public static ByteBuffer getImageHeader2(int length) {
+        ByteBuffer byteBuffer = ByteBuffer.allocate(172);
+        byteBuffer.order(ByteOrder.BIG_ENDIAN);
+        for (int ii = 0; ii < 159; ii++) {
+            byteBuffer.put((byte)0x00);
+        }
+        byteBuffer.putInt(length);  // 데이터 길이
+        for (int ii = 163; ii < 172; ii++) {
+            byteBuffer.put((byte)0x00);
+        }
+        return byteBuffer;
+    }
+
+    public static ByteBuffer getImageData(byte[] data) {
+        ByteBuffer byteBuffer = ByteBuffer.wrap(data);
+        byteBuffer.order(ByteOrder.BIG_ENDIAN);
+        return byteBuffer;
+    }
+
+}

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

@@ -1,6 +1,6 @@
 package com.its.vds.xnettcp.vds;
 
-import com.its.vds.config.LocalCommConfig;
+import com.its.vds.config.ControllerCommConfig;
 import com.its.vds.entity.TbVdsCtlr;
 import com.its.vds.xnettcp.vds.codec.VdsTcpClientDecoder;
 import com.its.vds.xnettcp.vds.codec.VdsTcpClientEncoder;
@@ -29,7 +29,7 @@ import java.util.concurrent.TimeUnit;
 public class VdsTcpClient implements Callable<Object> {
 
     private final TbVdsCtlr controller;
-    private final LocalCommConfig commConfig;
+    private final ControllerCommConfig commConfig;
     private final VdsDataProcess vdsDataProcess;
     private final VdsTcpClientBootstrapFactory bootstrapFactory;
 

+ 16 - 20
src/main/java/com/its/vds/xnettcp/vds/VdsTcpClientBootstrapFactory.java

@@ -1,16 +1,11 @@
 package com.its.vds.xnettcp.vds;
 
 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;
 import io.netty.channel.ChannelOption;
 import io.netty.channel.EventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
 import io.netty.channel.socket.nio.NioSocketChannel;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -42,21 +37,22 @@ public class VdsTcpClientBootstrapFactory {
         bootstrap.option(ChannelOption.SO_KEEPALIVE, false);
         bootstrap.option(ChannelOption.SO_KEEPALIVE, false);
         bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, this.connectTimeout * 1000);
-        bootstrap.handler(new ChannelInitializer<SocketChannel>() {
-            // VDS 전송 요청을 먼저하고 데이터를 수신한다.
-            // 핸들러가 실행되는 순서는 추가된 순서에 의해 결정된다.(Inbound: head=>tail, Outbound: tail=>head, name2ctx)
-            @Override
-            public void initChannel(SocketChannel ch) {
-                if (isLogging) {
-                    //io.netty.handler.logging.LoggingHandler
-                    //ch.pipeline().addLast(new LoggingHandler(LogLevel.WARN));
-                }
-                //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(vdsDataProcess));     // Packet Inbound handler
-                ch.pipeline().addLast("vdsClientEncoder",        new VdsTcpClientEncoder());            // Encoding handler
-            }
-        });
+//        bootstrap.handler(new ChannelInitializer<SocketChannel>() {
+//            // VDS 전송 요청을 먼저하고 데이터를 수신한다.
+//            // 핸들러가 실행되는 순서는 추가된 순서에 의해 결정된다.(Inbound: head=>tail, Outbound: tail=>head, name2ctx)
+//            @Override
+//            public void initChannel(SocketChannel ch) {
+//                if (isLogging) {
+//                    //io.netty.handler.logging.LoggingHandler
+//                    //ch.pipeline().addLast(new LoggingHandler(LogLevel.WARN));
+//                }
+//                ch.pipeline().addLast(new LoggingHandler(LogLevel.WARN));
+//                //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(vdsDataProcess));     // Packet Inbound handler
+//                ch.pipeline().addLast("vdsClientEncoder",        new VdsTcpClientEncoder());            // Encoding handler
+//            }
+//        });
 
         return bootstrap;
     }

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

@@ -1,6 +1,6 @@
 package com.its.vds.xnettcp.vds;
 
-import com.its.vds.config.LocalCommConfig;
+import com.its.vds.config.ControllerCommConfig;
 import com.its.vds.entity.TbVdsCtlr;
 import com.its.vds.global.AppRepository;
 import com.its.vds.xnettcp.vds.process.VdsDataProcess;
@@ -24,7 +24,7 @@ import java.util.concurrent.Future;
 @Service
 public class VdsTcpClientCommService {
 
-    private final LocalCommConfig commConfig;
+    private final ControllerCommConfig commConfig;
     private final VdsDataProcess vdsDataProcess;
 
     private VdsTcpClientBootstrapFactory bootstrapFactory;

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

@@ -16,6 +16,8 @@ import org.slf4j.MDC;
 
 import java.util.List;
 
+import static com.its.vds.xnettcp.vds.protocol.VdsProtocol.vds_DLE;
+
 @Slf4j
 public class VdsTcpClientDecoder extends ByteToMessageDecoder {
 
@@ -26,13 +28,13 @@ public class VdsTcpClientDecoder extends ByteToMessageDecoder {
         Channel channel = ctx.channel();
         TbVdsCtlr obj = AppRepository.getInstance().getCtlrIpMap().get(ipAddress);
         if (obj == null) {
-            log.error("TcpServerDecoder.decode: Unknown Controller IP: {}. will be close.", ipAddress);
+            log.error("VdsTcpClientDecoder.decode: Unknown Controller IP: {}. will be close.", ipAddress);
             VdsTcpClientIdleHandler.disconnectChannel(channel);
             return;
         }
 
         if (!channel.isOpen() || !channel.isActive()) {
-            log.error("TcpServerDecoder.decode: {}, isOpen: {}, isActive: {}. [{}]", ipAddress, channel.isOpen(), channel.isActive(), obj.getLogKey());
+            log.error("VdsTcpClientDecoder.decode: {}, isOpen: {}, isActive: {}. [{}]", ipAddress, channel.isOpen(), channel.isActive(), obj.getLogKey());
             VdsTcpClientIdleHandler.disconnectChannel(channel);
             return;
         }
@@ -45,12 +47,7 @@ public class VdsTcpClientDecoder extends ByteToMessageDecoder {
             if (obj.isDump()) {
                 byte[] debugBytes = new byte[byteBuf.readableBytes()];
                 byteBuf.getBytes(byteBuf.readerIndex(), debugBytes);
-                log.info("RECV: [{}], {} Bytes. {}", ipAddress, debugBytes.length, SysUtils.byteArrayToHex(debugBytes));
-            }
-
-            if (readableBytes < VdsProtocol.MIN_PACKET_SIZE) {
-                log.error("RECV: {}. byteBuf.readableBytes() == 0. [{]{}]", ipAddress, obj.getLogKey());
-                return;
+                log.info("RECV_0: [{}], {} Bytes. {}", ipAddress, debugBytes.length, SysUtils.byteArrayToHex(debugBytes));
             }
 
             byteBuf.markReaderIndex();
@@ -58,66 +55,68 @@ public class VdsTcpClientDecoder extends ByteToMessageDecoder {
             byte[] packets = new byte[readableBytes];
             byteBuf.readBytes(recvBytes);
 
-            int readIdx = 0;
+            int stuffing = 0;
             int msgSize = 0;        // 순수 데이터 사이즈
-            int totalMsgSize = 0;   // 전체 수신한 패킷 사이즈
             boolean foundDle = false;
-            boolean remainPacket = false;
-
-            while (true) {
-                if (VdsProtocol.MIN_PACKET_SIZE > (readableBytes-totalMsgSize)) {
-                    break;
+            boolean requiredEtx = false;
+            for (int readIdx = 0; readIdx < readableBytes; readIdx++) {
+                if (readIdx == 2) {
+                    if (recvBytes[0] != VdsProtocol.vds_DLE || recvBytes[1] != VdsProtocol.vds_STX) {
+                        log.error("RECV_0: [{}]. DLE/STX Data Error. {}/{}", ipAddress, recvBytes[0], recvBytes[1]);
+                        VdsTcpClientIdleHandler.disconnectChannel(channel);
+                        return;
+                    }
                 }
 
-                msgSize = 0;
-                foundDle = false;
-                for (readIdx = totalMsgSize; readIdx < readableBytes; readIdx++) {
-                    byte data = recvBytes[readIdx];
-                    if (foundDle) {
-                        foundDle = false;
-                        if (data == VdsProtocol.vds_DLE) {
-                            // 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
-                            packets[msgSize++] = data;
-                        } else if (data == VdsProtocol.vds_ETX) {
-                            // 이전데이터가 DLE 이고 현재 데이터가 ETX 이면 패킷의 끝임.
-                            // 다음 2바이트는 CRC 데이터임, 남아 있는 데이터가 CRC 2바이트를 포함한 크기보다 작으면
-                            // 하나의 패킷을 완전히 수신하지 못한 것임
-                            if ((readIdx + 3) > (readableBytes)) {
-                                // 하나의 패킷을 읽지 못함
-                                remainPacket = true;
-                                log.warn("RECV_0: [{}]. ReadableBytes: {} Bytes, ReadIndex: {}, DLE Data Remain.", ipAddress, readableBytes, readIdx);
-                                break;
-                            }
-                            packets[msgSize++] = data;
-                            packets[msgSize++] = recvBytes[readIdx+1];  // CRC1
-                            packets[msgSize++] = recvBytes[readIdx+2];  // CRC2
-
-                            // 하나의 패킷을 읽었음 ***************
-                            totalMsgSize += msgSize;
-                            byteBuf.readerIndex(msgSize);
-                            byteBuf.markReaderIndex();
-                            byteBuf.discardReadBytes();
-
-                            VdsResFramePacket packet = new VdsResFramePacket(obj, packets, msgSize);
-                            log.info("OnePacket: {} Bytes, {}", packet.getByteBuffer().array().length, SysUtils.byteArrayToHex(packet.getByteBuffer().array()));
-                            list.add(packet);
+                byte data = recvBytes[readIdx];
+                if (foundDle) {
+                    foundDle = false;
+                    if (data == VdsProtocol.vds_DLE) {
+                        // Skip DLE Stuffing Data
+                        stuffing++;
+                        //log.warn("RECV_0: [{}]. ReadableBytes: {} Bytes, ReadIndex: {}, DLE Stuffing Data Recv.", ipAddress, readableBytes, readIdx);
+                    } else if (data == VdsProtocol.vds_STX) {
+                        // Packet
+                        packets[msgSize++] = data;
+                    } else if (data == VdsProtocol.vds_ETX) {
+                        packets[msgSize++] = data;
+
+                        // 이전데이터가 DLE 이고 현재 데이터가 ETX 이면 패킷의 끝임.
+                        // 다음 2바이트는 CRC 데이터임, 남아 있는 데이터가 CRC 2바이트를 포함한 크기보다 작으면
+                        // 하나의 패킷을 완전히 수신하지 못한 것임
+                        if ((readIdx + 2) > (readableBytes)) {
+                            // 하나의 패킷을 읽지 못함
+                            log.warn("RECV_0: [{}]. ReadableBytes: {} Bytes, ReadIndex: {}, DLE Data Remain.", ipAddress, readableBytes, readIdx);
                             break;
+                        }
+                        packets[msgSize++] = recvBytes[readIdx+1];  // CRC1
+                        packets[msgSize++] = recvBytes[readIdx+2];  // CRC2
+
+                        // 하나의 패킷을 읽었음 ***************
+                        byteBuf.readerIndex(readIdx+3);
+                        byteBuf.markReaderIndex();
+                        byteBuf.discardReadBytes();
+
+                        VdsResFramePacket frame = new VdsResFramePacket(obj, packets, msgSize);
+                        if (frame.getHead().getOpCode() == VdsProtocol.vds_Image) {
+                            log.info("OneFramePacket: {} Bytes, vds_Image, stuffing {}", frame.getByteBuffer().array().length, stuffing);
                         } else {
-                            // DLE 다음에 와야할 데이터가 들어오지 않았다. 패킷에 오류가 발생함.
-                            log.warn("RECV_0: [{}]. ReadableBytes: {} Bytes, ReadIndex: {}, DLE Next Data Recv Error.", ipAddress, readableBytes, readIdx);
+                            log.info("OneFramePacket: {} Bytes, stuffing {} {}", frame.getByteBuffer().array().length, stuffing, SysUtils.byteArrayToHex(frame.getByteBuffer().array()));
                         }
+
+                        list.add(frame);
+                        break;
                     } else {
-                        packets[msgSize++] = data;
-                        if (data == VdsProtocol.vds_DLE) {
-                            foundDle = true;
-                        }
+                        // DLE 다음에 와야할 데이터가 들어오지 않았다. 패킷에 오류가 발생함.
+                        log.error("RECV_0: [{}]. ReadableBytes: {} Bytes, ReadIndex: {}, DLE Next Data Recv Error.", ipAddress, readableBytes, readIdx);
+                        VdsTcpClientIdleHandler.disconnectChannel(channel);
+                        return;
+                    }
+                } else {
+                    packets[msgSize++] = data;
+                    if (data == vds_DLE) {
+                        foundDle = true;
                     }
-                }
-                if (totalMsgSize >= readableBytes || remainPacket) {
-                    break;
                 }
             }
         }

+ 32 - 19
src/main/java/com/its/vds/xnettcp/vds/process/Job_Image.java

@@ -2,6 +2,7 @@ package com.its.vds.xnettcp.vds.process;
 
 import com.its.app.utils.NettyUtils;
 import com.its.vds.entity.TbVdsCtlr;
+import com.its.vds.xnettcp.center.protocol.CenterResProtocol;
 import com.its.vds.xnettcp.vds.protocol.VdsProtocol;
 import com.its.vds.xnettcp.vds.protocol.VdsReqImage;
 import com.its.vds.xnettcp.vds.protocol.VdsResFramePacket;
@@ -29,7 +30,7 @@ public class Job_Image implements JobProtocol {
 
 		byte[] body = this.packet.getBody();
 		if (body == null || body.length < 6) {
-			log.error("Job_Image, [{}]: Data Length Error, {}", this.packet.getObjectInfo(), (body == null) ? 0 : body.length);
+			log.error("Job_Image, [{}]: Data Body Length Error, {}", this.packet.getObjectInfo(), (body == null) ? 0 : body.length);
 			return 0;
 		}
 
@@ -37,57 +38,69 @@ public class Job_Image implements JobProtocol {
 		ByteBuffer byteBuffer = ByteBuffer.wrap(body);
 		byteBuffer.order(VdsProtocol.byteOrder);
 
+		int pktSize = byteBuffer.array().length;
 		int total = byteBuffer.getShort();
 		int current = byteBuffer.getShort();
 		int dataLen = byteBuffer.getShort();
 
-		log.info("Job_Image: image data receive: total {}, current {}, dataLen {}", total, current, dataLen);
+		log.info("Job_Image: image data receive: total {}, current {}, dataLen {}, pktSize {}", total, current, dataLen, pktSize);
 
 		if (dataLen > 6) {
 			int imageSize = dataLen - 6;
-			byte[] imageData = new byte[imageSize-6];
+			byte[] imageData = new byte[imageSize];
 			byteBuffer.get(imageData);
 			obj.addImageSize(imageSize);
+			obj.addImageData(imageData);
+			log.info("Job_Image: image data save: currentSize {}, totalSize {}", imageSize, obj.getImageData().array().length);
+		}
+		else {
+			log.error("Job_Image: image data receive size error: total {}, current {}, dataLen {}", total, current, dataLen);
+			obj.setStopImageResponse();
+			return 0;
 		}
 
-		if (total == current) {
+		int nextFrame = current+1;
+		if (total == nextFrame) {
 			log.info("Job_Image, completed image data receive: {}", obj.getImageSize());
 			List<Channel> channels = obj.getRequestImageList();
-
-			byte[] head1 = new byte[10];
-			byte[] head2 = new byte[172];
-			byte[] data  = new byte[33];
-
-			ByteBuffer buffer1 = ByteBuffer.wrap(head1);
-
-			ByteBuffer buffer2 = ByteBuffer.wrap(head2);
-			ByteBuffer buffer3 = ByteBuffer.wrap(data);
+			ByteBuffer buffer1 = CenterResProtocol.getImageHeader1();
+			ByteBuffer buffer2 = CenterResProtocol.getImageHeader2(obj.getImageSize());
+			ByteBuffer buffer3 = obj.getImageData();
 			channels.forEach(channel -> {
-				sendResponse(channel, buffer1);
+				if (sendCenterResponse(channel, buffer1)) {
+					log.info("Job_Image, send image data to center[HEAD1]: {} Bytes. {}", buffer1.array().length, NettyUtils.getRemoteAddress(channel));
+				}
 			});
 			channels.forEach(channel -> {
-				sendResponse(channel, buffer2);
+				if (sendCenterResponse(channel, buffer2)) {
+					log.info("Job_Image, send image data to center[HEAD2]: {} Bytes. {}", buffer2.array().length, NettyUtils.getRemoteAddress(channel));
+				}
 			});
 			channels.forEach(channel -> {
-				sendResponse(channel, buffer3);
+				if (sendCenterResponse(channel, buffer3)) {
+					log.info("Job_Image, send image data to center[DATA]: {} Bytes. {}", buffer3.array().length, NettyUtils.getRemoteAddress(channel));
+				}
 			});
 		}
 		else {
 			VdsReqImage reqImage = new VdsReqImage((short)obj.getGROUP_NO(), (short)obj.getVDS_CTLR_LOCAL_NO());
 			reqImage.setCameraNo(obj.getCameraNo());
-			reqImage.setFrameNo(current+1);
+			reqImage.setFrameNo(nextFrame);
 			reqImage.makeCRC();
 			ByteBuffer sendBuffer = reqImage.getByteBuffer();
 			if (!obj.sendData(sendBuffer, 0, "vds_Image")) {
-				log.error("Job_Image, request data failed: total {}, frameNo {}", total, current+1);
+				log.error("Job_Image, request data failed: total {}, frameNo {}", total, nextFrame);
 				obj.setStopImageResponse();
+			} else {
+				log.info("Job_Image: next image request, total {}, current {}, next {}", total, current, nextFrame);
 			}
 		}
 		return 0;
 	}
 
-	public boolean sendResponse(Channel channel, ByteBuffer sendBuff) {
+	public boolean sendCenterResponse(Channel channel, ByteBuffer sendBuff) {
 		boolean result = false;
+		log.error("Job_Image, sendCenterResponse {} Bytes", sendBuff.array().length);
 		if (channel != null) {
 			ChannelFuture f = channel.writeAndFlush(sendBuff);
 			f.awaitUninterruptibly();

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

@@ -173,7 +173,7 @@ public class VdsDataProcess {
 
     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());
+        log.info("RECV_P: [{}], RECV.{}, [{}] checkStatus.", obj.getVDS_CTLR_IP(), opCodeName, obj.getVDS_CTLR_NMBR());
 
         /*
          * VDS Status Update
@@ -210,7 +210,7 @@ public class VdsDataProcess {
         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);
+        log.info("checkStatus, 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";

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

@@ -26,7 +26,7 @@ public class VdsResFramePacket {
 
             // BODY
             int bodyLength = size - VdsResFrameHead.SIZE - VdsResFrameTail.SIZE;
-            log.error("size: {}, BodyLength: {}", size, bodyLength);
+            log.info("FrameSize: {}, BodyLength: {}", size, bodyLength);
             if (bodyLength > 0) {
                 this.body = new byte[bodyLength];
                 System.arraycopy(packet, VdsResFrameHead.SIZE, this.body, 0, bodyLength);

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

@@ -15,7 +15,7 @@ public class VdsResFrameTail {
 
     public VdsResFrameTail(byte[] packet, int tailPos) {
 
-        log.error("{}, {}", packet.length, tailPos);
+        //log.error("{}, {}", packet.length, tailPos);
         this.dle = packet[tailPos+0];
         this.etx = packet[tailPos+1];
         this.crc = (short)((packet[tailPos+2] << 8 | packet[tailPos+3]) & 0xFFFF);

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

@@ -14,7 +14,7 @@ application:
     send-port: 5701
     recv-port: 5202
 
-  local-comm:
+  controller-comm:
     comm-logging: true
     retry-seconds: 10
     connect-timeout: 5