shjung %!s(int64=3) %!d(string=hai) anos
pai
achega
4571dbcc9a
Modificáronse 41 ficheiros con 1470 adicións e 297 borrados
  1. 0 1
      conf/vds-comm-server.pid
  2. 176 2
      src/main/java/com/its/app/utils/NettyUtils.java
  3. 14 12
      src/main/java/com/its/vds/VdsCommServerApplication.java
  4. 1 1
      src/main/java/com/its/vds/config/CenterCommConfig.java
  5. 1 1
      src/main/java/com/its/vds/config/FacilityManagerConfig.java
  6. 32 0
      src/main/java/com/its/vds/config/LocalCommConfig.java
  7. 1 1
      src/main/java/com/its/vds/config/ProcessConfig.java
  8. 22 18
      src/main/java/com/its/vds/config/SystemInfo.java
  9. 1 0
      src/main/java/com/its/vds/config/ThreadPoolInitializer.java
  10. 4 5
      src/main/java/com/its/vds/dao/mapper/VdsDtctMapper.java
  11. 39 3
      src/main/java/com/its/vds/entity/TbVdsCtlr.java
  12. 19 14
      src/main/java/com/its/vds/entity/voVdsDtctClct.java
  13. 2 2
      src/main/java/com/its/vds/process/DbmsJobProcess.java
  14. 24 24
      src/main/java/com/its/vds/scheduler/SchedulerTask.java
  15. 11 11
      src/main/java/com/its/vds/service/StatisticsServices.java
  16. 3 0
      src/main/java/com/its/vds/service/VdsCtlrService.java
  17. 1 1
      src/main/java/com/its/vds/xnettcp/handler/TcpServerIdleStateHandler.java
  18. 152 0
      src/main/java/com/its/vds/xnettcp/vds/VdsTcpClient.java
  19. 68 0
      src/main/java/com/its/vds/xnettcp/vds/VdsTcpClientBootstrapFactory.java
  20. 71 0
      src/main/java/com/its/vds/xnettcp/vds/VdsTcpClientCommService.java
  21. 114 0
      src/main/java/com/its/vds/xnettcp/vds/codec/VdsTcpClientDecoder.java
  22. 28 0
      src/main/java/com/its/vds/xnettcp/vds/codec/VdsTcpClientEncoder.java
  23. 93 0
      src/main/java/com/its/vds/xnettcp/vds/handler/VdsTcpClientIdleHandler.java
  24. 17 0
      src/main/java/com/its/vds/xnettcp/vds/handler/VdsTcpClientInboundHandler.java
  25. 20 0
      src/main/java/com/its/vds/xnettcp/vds/handler/VdsTcpClientOutboundHandler.java
  26. 137 0
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsProtocol.java
  27. 11 0
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqData.java
  28. 48 0
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqFrameHead.java
  29. 77 0
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqFramePacket.java
  30. 21 0
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqFrameTail.java
  31. 17 0
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqSynchronize.java
  32. 11 0
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqTemperature.java
  33. 15 0
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsResFrameHead.java
  34. 8 0
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsResFramePacket.java
  35. 11 0
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsResFrameTail.java
  36. 8 0
      src/main/java/com/its/vds/xnettcp/vds/protocol/VdsUtils.java
  37. 8 0
      src/main/resources/application.yml
  38. 0 0
      src/main/resources/logback-spring.xmlx
  39. 2 1
      src/main/resources/mybatis/mapper/VdsCtlrMapper.xml
  40. 104 112
      src/main/resources/mybatis/mapper/VdsDtctMapper.xml
  41. 78 88
      src/main/resources/mybatis/mapper/VdsStatMapper.xml

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

@@ -1 +0,0 @@
-21532

+ 176 - 2
src/main/java/com/its/app/utils/NettyUtils.java

@@ -1,9 +1,24 @@
 package com.its.app.utils;
 
 import io.netty.channel.Channel;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.epoll.Epoll;
+import io.netty.channel.epoll.EpollEventLoopGroup;
+import io.netty.channel.epoll.EpollServerSocketChannel;
+import io.netty.channel.epoll.EpollSocketChannel;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.ServerSocketChannel;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.util.concurrent.DefaultThreadFactory;
+import lombok.extern.slf4j.Slf4j;
 
-import java.net.InetSocketAddress;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.Enumeration;
 
+@Slf4j
 public final class NettyUtils {
 
     public static String getTcpAddress(Channel ch) {
@@ -69,4 +84,163 @@ public final class NettyUtils {
             port = inetAddr.getPort();
         return port;
     }
-}
+    public static boolean isEpollAvailable() {
+        // Netty epoll transport does not work with WSL (Windows Sybsystem for Linux) yet.
+/*
+        boolean HAS_WSLENV = System.getenv("WSLENV") != null;
+        return Epoll.isAvailable() && !HAS_WSLENV;
+*/
+        return Epoll.isAvailable();
+    }
+
+    public static EventLoopGroup newEventLoopGroup(int nThreads, String threadPoolName) {
+        if (isEpollAvailable()) {
+            if (threadPoolName.equals("")) {
+                return new EpollEventLoopGroup(nThreads);
+            }
+            else {
+                return new EpollEventLoopGroup(nThreads, new DefaultThreadFactory("epo"+threadPoolName));
+            }
+        } else {
+            if (threadPoolName.equals("")) {
+                return new NioEventLoopGroup(nThreads);
+            }
+            else {
+                return new NioEventLoopGroup(nThreads, new DefaultThreadFactory("nio" + threadPoolName));
+            }
+        }
+    }
+
+    public static Class<? extends SocketChannel> getSocketChannel() {
+        if (isEpollAvailable()) {
+            return EpollSocketChannel.class;
+        } else {
+            return NioSocketChannel.class;
+        }
+    }
+
+    public static Class<? extends ServerSocketChannel> getServerSocketChannel() {
+        if (isEpollAvailable()) {
+            return EpollServerSocketChannel.class;
+        } else {
+            return NioServerSocketChannel.class;
+        }
+    }
+
+    public static final String OS_NAME = System.getProperty("os.name");
+    private static boolean isLinuxPlatform = false;
+    private static boolean isWindowsPlatform = false;
+
+    static {
+        if (OS_NAME != null && OS_NAME.toLowerCase().contains("linux")) {
+            isLinuxPlatform = true;
+        }
+
+        if (OS_NAME != null && OS_NAME.toLowerCase().contains("windows")) {
+            isWindowsPlatform = true;
+        }
+    }
+
+    public static String getLocalAddress() {
+        // Traversal Network interface to get the first non-loopback and non-private address
+        Enumeration<NetworkInterface> enumeration = null;
+        try {
+            enumeration = NetworkInterface.getNetworkInterfaces();
+        } catch (SocketException e) {
+            log.error("getLocalAddress: getNetworkInterfaces");
+            return null;
+        }
+        ArrayList<String> ipv4Result = new ArrayList<String>();
+        ArrayList<String> ipv6Result = new ArrayList<String>();
+        while (enumeration.hasMoreElements()) {
+            final NetworkInterface networkInterface = enumeration.nextElement();
+            final Enumeration<InetAddress> en = networkInterface.getInetAddresses();
+            while (en.hasMoreElements()) {
+                final InetAddress address = en.nextElement();
+                if (!address.isLoopbackAddress()) {
+                    if (address instanceof Inet6Address) {
+                        ipv6Result.add(normalizeHostAddress(address));
+                    } else {
+                        ipv4Result.add(normalizeHostAddress(address));
+                    }
+                }
+            }
+        }
+
+        // prefer ipv4
+        if (!ipv4Result.isEmpty()) {
+            for (String ip : ipv4Result) {
+                if (ip.startsWith("127.0") || ip.startsWith("192.168")) {
+                    continue;
+                }
+                return ip;
+            }
+
+            return ipv4Result.get(ipv4Result.size() - 1);
+        } else if (!ipv6Result.isEmpty()) {
+            return ipv6Result.get(0);
+        }
+        //If failed to find,fall back to localhost
+        final InetAddress localHost;
+        try {
+            localHost = InetAddress.getLocalHost();
+        } catch (UnknownHostException e) {
+            log.error("getLocalAddress: UnknownHostException");
+            return null;
+        }
+        return normalizeHostAddress(localHost);
+    }
+
+    public static String normalizeHostAddress(final InetAddress localHost) {
+        if (localHost instanceof Inet6Address) {
+            return "[" + localHost.getHostAddress() + "]";
+        } else {
+            return localHost.getHostAddress();
+        }
+    }
+
+    public static SocketAddress string2SocketAddress(final String addr) {
+        String[] s = addr.split(":");
+        InetSocketAddress isa = new InetSocketAddress(s[0], Integer.parseInt(s[1]));
+        return isa;
+    }
+
+    public static String socketAddress2String(final SocketAddress addr) {
+        StringBuilder sb = new StringBuilder();
+        InetSocketAddress inetSocketAddress = (InetSocketAddress) addr;
+        sb.append(inetSocketAddress.getAddress().getHostAddress());
+        sb.append(":");
+        sb.append(inetSocketAddress.getPort());
+        return sb.toString();
+    }
+
+    public static String parseChannelRemoteAddr(final Channel channel) {
+        if (null == channel) {
+            return "";
+        }
+        SocketAddress remote = channel.remoteAddress();
+        final String addr = remote != null ? remote.toString() : "";
+
+        if (addr.length() > 0) {
+            int index = addr.lastIndexOf("/");
+            if (index >= 0) {
+                return addr.substring(index + 1);
+            }
+
+            return addr;
+        }
+
+        return "";
+    }
+
+    public static String parseSocketAddressAddr(SocketAddress socketAddress) {
+        if (socketAddress != null) {
+            final String addr = socketAddress.toString();
+
+            if (addr.length() > 0) {
+                return addr.startsWith("/") ? addr.substring(1) : addr;
+            }
+        }
+        return "";
+    }
+}

+ 14 - 12
src/main/java/com/its/vds/VdsCommServerApplication.java

@@ -5,9 +5,8 @@ import com.its.vds.config.ProcessConfig;
 import com.its.vds.process.DbmsJobProcess;
 import com.its.vds.service.UnitSystService;
 import com.its.vds.service.VdsCtlrService;
-import com.its.vds.xnettcp.TcpServerVdsComm;
 import com.its.vds.xnettcp.process.TcpServerDataProcess;
-import com.its.vds.xnetudp.UdpServerCenterComm;
+import com.its.vds.xnettcp.vds.VdsTcpClientCommService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.catalina.connector.Connector;
 import org.springframework.beans.factory.DisposableBean;
@@ -78,11 +77,11 @@ public class VdsCommServerApplication implements CommandLineRunner, ApplicationL
         ctlrService.loadDb();
         ctlrService.updateCtlrStts(true);
 
-        TcpServerVdsComm tcpServersComm = (TcpServerVdsComm)AppUtils.getBean(TcpServerVdsComm.class);
-        tcpServersComm.run();
-
-        UdpServerCenterComm udpServerCenterComm = (UdpServerCenterComm)AppUtils.getBean(UdpServerCenterComm.class);
-        udpServerCenterComm.run();
+        VdsTcpClientCommService vdsCommClientService = (VdsTcpClientCommService)AppUtils.getBean(VdsTcpClientCommService.class);
+        vdsCommClientService.run();
+//
+//        UdpServerCenterComm udpServerCenterComm = (UdpServerCenterComm)AppUtils.getBean(UdpServerCenterComm.class);
+//        udpServerCenterComm.run();
 
         // schedule enable
         processConfig.setStartSchedule(true);
@@ -108,12 +107,15 @@ public class VdsCommServerApplication implements CommandLineRunner, ApplicationL
         VdsCtlrService ctlrService = (VdsCtlrService) AppUtils.getBean(VdsCtlrService.class);
         ctlrService.updateCtlrStts(false);
 
-        TcpServerVdsComm tcpServersComm = (TcpServerVdsComm)AppUtils.getBean(TcpServerVdsComm.class);
-        tcpServersComm.getAcceptGroups().shutdownGracefully();
-        tcpServersComm.getWorkerGroups().shutdownGracefully();
+        VdsTcpClientCommService vdsCommClientService = (VdsTcpClientCommService)AppUtils.getBean(VdsTcpClientCommService.class);
+        vdsCommClientService.shutdown();
+
+//        TcpServerVdsComm tcpServersComm = (TcpServerVdsComm)AppUtils.getBean(TcpServerVdsComm.class);
+//        tcpServersComm.getAcceptGroups().shutdownGracefully();
+//        tcpServersComm.getWorkerGroups().shutdownGracefully();
 
-        UdpServerCenterComm udpServerCenterComm = (UdpServerCenterComm)AppUtils.getBean(UdpServerCenterComm.class);
-        udpServerCenterComm.getNioEventLoopGroup().shutdownGracefully();
+//        UdpServerCenterComm udpServerCenterComm = (UdpServerCenterComm)AppUtils.getBean(UdpServerCenterComm.class);
+//        udpServerCenterComm.getNioEventLoopGroup().shutdownGracefully();
     }
     @Override
     public void afterPropertiesSet() throws Exception {

+ 1 - 1
src/main/java/com/its/vds/config/CenterCommConfig.java

@@ -22,7 +22,7 @@ public class CenterCommConfig {
 
     @PostConstruct
     private void init() {
-        log.info("CenterCommConfig: {}", this);
+        log.info("{}", this);
     }
 
 }

+ 1 - 1
src/main/java/com/its/vds/config/FacilityManagerConfig.java

@@ -26,7 +26,7 @@ public class FacilityManagerConfig {
     private void init() {
         if (this.ipAddr.equals(""))
             this.enable = false;
-        log.info("FacilityManagerConfig: {}", this);
+        log.info("{}", this);
     }
 
 }

+ 32 - 0
src/main/java/com/its/vds/config/LocalCommConfig.java

@@ -0,0 +1,32 @@
+package com.its.vds.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.PostConstruct;
+
+@Slf4j
+@Getter
+@Setter
+@ToString
+@Configuration
+@ConfigurationProperties(prefix = "application.local-comm")
+public class LocalCommConfig {
+
+    private boolean commLogging = false;
+    private int retrySeconds = 10;
+    private int connectTimeout = 5;
+    private int readerIdleTime = 10;
+    private int writerIdleTime = 0;
+    private int allIdleTime = 0;
+
+    @PostConstruct
+    private void init() {
+        log.info("{}", this);
+    }
+
+}

+ 1 - 1
src/main/java/com/its/vds/config/ProcessConfig.java

@@ -50,6 +50,6 @@ public class ProcessConfig {
 
         this.bootingDateTime = SysUtils.getSysTimeStr();
 
-        log.info("ProcessConfig: {}", this);
+        log.info("{}", this);
     }
 }

+ 22 - 18
src/main/java/com/its/vds/config/SystemInfo.java

@@ -8,10 +8,7 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.core.env.Environment;
 
 import javax.annotation.PostConstruct;
-import java.net.InetAddress;
-import java.net.InterfaceAddress;
-import java.net.NetworkInterface;
-import java.net.UnknownHostException;
+import java.net.*;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Enumeration;
@@ -43,46 +40,53 @@ public class SystemInfo {
         setCpuCores(Integer.valueOf(Runtime.getRuntime().availableProcessors()));
         setHostName(getLocalHostName());
         setIpAddress(getLocalIpAddress());
+
+        log.info("{}", this);
     }
     private String getLocalHostName() {
         String hostName = null;
         try {
             hostName = InetAddress.getLocalHost().getHostName();
         } catch (UnknownHostException e) {
-            System.out.println(e.getMessage() + ", " + e.getStackTrace());
+            log.error("getLocalHostName: UnknownHostException");
         }
         return hostName;
     }
 
     private String getLocalIpAddress() {
         List<String> ipAddresses = new ArrayList<String>();
+        Enumeration<NetworkInterface> e = null;
         try {
-            Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
-            while (e.hasMoreElements()) {
-                for (InterfaceAddress ifAddr : ((NetworkInterface)e.nextElement()).getInterfaceAddresses()) {
-                    if (!(ifAddr.getAddress() instanceof java.net.Inet6Address))
-                        ipAddresses.add(ifAddr.getAddress().getHostAddress());
-                }
+            e = NetworkInterface.getNetworkInterfaces();
+        } catch (SocketException ex) {
+            log.error("getLocalIpAddress: SocketException");
+            return "127.0.0.1";
+        }
+        while (e.hasMoreElements()) {
+            for (InterfaceAddress ifAddr : ((NetworkInterface)e.nextElement()).getInterfaceAddresses()) {
+                if (!(ifAddr.getAddress() instanceof java.net.Inet6Address))
+                    ipAddresses.add(ifAddr.getAddress().getHostAddress());
             }
-        } catch (Exception e) {
-            System.out.println(e.getMessage() + ", " + e.getStackTrace());
         }
+
         return ipAddresses.toString();
     }
 
     public List<String> getIpAddressesList() {
         List<String> ipAddresses = new ArrayList<>();
+        Enumeration<NetworkInterface> e = null;
         try {
-            Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
-            while (e.hasMoreElements()) {
+            e = NetworkInterface.getNetworkInterfaces();
+        } catch (SocketException ex) {
+            log.error("getIpAddressesList: SocketException");
+            return ipAddresses;
+        }
+        while (e.hasMoreElements()) {
                 for (InterfaceAddress ifAddr : ((NetworkInterface)e.nextElement()).getInterfaceAddresses()) {
                     if (!(ifAddr.getAddress() instanceof java.net.Inet6Address))
                         ipAddresses.add(ifAddr.getAddress().getHostAddress());
                 }
             }
-        } catch (Exception e) {
-            System.out.println(e.getMessage() + ", " + e.getStackTrace());
-        }
         return ipAddresses;
     }
 }

+ 1 - 0
src/main/java/com/its/vds/config/ThreadPoolInitializer.java

@@ -49,6 +49,7 @@ public class ThreadPoolInitializer extends AsyncConfigurerSupport {
         if (this.ping <= 0) {
             this.ping = MAX_CORE;
         }
+
         log.info("{}", this);
     }
 

+ 4 - 5
src/main/java/com/its/vds/dao/mapper/VdsDtctMapper.java

@@ -2,8 +2,6 @@ package com.its.vds.dao.mapper;
 
 import com.its.vds.entity.TbVdsDtct;
 import com.its.vds.entity.voVdsDtctClct;
-import com.its.vds.entity.voVdsDtctStts;
-import com.its.vds.entity.voVdsDtctVehClct;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
@@ -13,10 +11,11 @@ import java.util.List;
 public interface VdsDtctMapper {
 
     List<TbVdsDtct> selectAll();
-    int          	updateVdsDtctStts(@Param("stts") voVdsDtctStts paramVdsCtlrStts);
-    int          	insertVdsDtctSttsHs(@Param("stts") voVdsDtctStts paramVdsCtlrStts);
     int          	insertVdsDtctClct(@Param("clct") voVdsDtctClct paramVdsDtctClct);
     int          	updateVdsDtctClctPnst(@Param("clct") voVdsDtctClct paramVdsDtctClct);
-    int          	insertVdsDtctVehClct(@Param("clct") voVdsDtctVehClct paramVdsDtctVehClct);
+
+    //int          	updateVdsDtctStts(@Param("stts") voVdsDtctStts paramVdsCtlrStts);
+    //int          	insertVdsDtctSttsHs(@Param("stts") voVdsDtctStts paramVdsCtlrStts);
+    //int          	insertVdsDtctVehClct(@Param("clct") voVdsDtctVehClct paramVdsDtctVehClct);
     
 }

+ 39 - 3
src/main/java/com/its/vds/entity/TbVdsCtlr.java

@@ -2,6 +2,9 @@ package com.its.vds.entity;
 
 import com.its.app.utils.SysUtils;
 import com.its.vds.domain.NET;
+import com.its.vds.xnettcp.vds.protocol.VdsReqData;
+import com.its.vds.xnettcp.vds.protocol.VdsReqSynchronize;
+import com.its.vds.xnettcp.vds.protocol.VdsReqTemperature;
 import io.netty.channel.Channel;
 import lombok.Getter;
 import lombok.Setter;
@@ -40,7 +43,7 @@ public class TbVdsCtlr {
 	private boolean       			isDupCon;
 	private boolean                 isDupLogin;
 	private String 		 			dstIpAddr;
-	private TbVdsCtlrStts stts;
+	private TbVdsCtlrStts 			stts;
 	private Channel 				channel;
 	private Channel 				dupChannel;
 	private long          			syncTime;
@@ -49,6 +52,11 @@ public class TbVdsCtlr {
 	private int connectCount;
 	private String connectTm;
 	private String disConnectTm;
+
+	VdsReqSynchronize reqSynchronize = null;
+	VdsReqData reqData = null;
+	VdsReqTemperature reqTemperature = null;
+
 	public TbVdsCtlr() {
 		this.vdsDtctMap = Collections.synchronizedMap(new HashMap<String, TbVdsDtct>());
 		this.stts = new TbVdsCtlrStts();
@@ -63,16 +71,19 @@ public class TbVdsCtlr {
 	public String getLogKey() {
 		return this.VDS_CTLR_ID;
 	}
+
 	public void resetConnectCount() {
 		if (this.netState == NET.CLOSED)
 			this.connectCount = 0;
 		else
 			this.connectCount = 1;
 	}
+
 	public void setConnectTm() {
 		this.connectTm = SysUtils.getSysTimeStr();
 		this.connectCount++;
 	}
+
 	public void setDisConnectTm() {
 		this.disConnectTm = SysUtils.getSysTimeStr();
 	}
@@ -87,18 +98,43 @@ public class TbVdsCtlr {
 		this.cliReq     = null;
 		this.syncTime   = 0;
 	}
-	public synchronized void channelLogin(Channel channel) {
+
+	public synchronized void channelOpen(Channel channel) {
 		this.netState = NET.LOGIN_REQ;
 		this.channel = channel;
 		getStts().initStts(true);
 		setConnectTm();
 	}
 
-	public synchronized void channelLogout() {
+	public synchronized void channelLogin(Channel channel) {
+		this.netState = NET.LOGINED;
+		this.channel = channel;
+		getStts().initStts(true);
+		setConnectTm();
+	}
+
+	public synchronized void channelClosed() {
 		this.netState = NET.CLOSED;
 		this.channel = null;
 		getStts().initStts(false);
 		setDisConnectTm();
 	}
 
+	/**
+	 * 통신 패킷 초기화
+	 */
+	public void initReqPacket() {
+		if (this.reqSynchronize == null) {
+			this.reqSynchronize = new VdsReqSynchronize((short)this.GROUP_NO, (short)this.VDS_CTLR_LOCAL_NO);
+			this.reqData.makeCRC();
+		}
+		if (this.reqData == null) {
+			this.reqData = new VdsReqData((short)this.GROUP_NO, (short)this.VDS_CTLR_LOCAL_NO);
+			this.reqData.makeCRC();
+		}
+		if (this.reqTemperature == null) {
+			this.reqTemperature = new VdsReqTemperature((short)this.GROUP_NO, (short)this.VDS_CTLR_LOCAL_NO);
+			this.reqData.makeCRC();
+		}
+	}
 }

+ 19 - 14
src/main/java/com/its/vds/entity/voVdsDtctClct.java

@@ -11,6 +11,7 @@ public class voVdsDtctClct {
 
 	private String VDS_DTCT_NMBR;
 	private String CLCT_DT;
+	private String SYST_KIND_DVSN;
 	private int    TRAF_CLCT_CYCL;
 	private int    TFVL;
 	private int    SPED;
@@ -23,25 +24,29 @@ public class voVdsDtctClct {
 	private boolean isValid;
 
 	public voVdsDtctClct() {
-		VDS_DTCT_NMBR = "";
-		CLCT_DT       = "";
+		this.VDS_DTCT_NMBR  = "";
+		this.CLCT_DT        = "";
+		this.SYST_KIND_DVSN = "";
+
 		initVal();
 	}
-	public voVdsDtctClct(String vdsDtctNmbr, String clctDt) {
-		VDS_DTCT_NMBR = vdsDtctNmbr;
-		CLCT_DT       = clctDt;
+	public voVdsDtctClct(String vdsDtctNmbr, String clctDt, String systKindDvsn) {
+		this.VDS_DTCT_NMBR  = vdsDtctNmbr;
+		this.CLCT_DT        = clctDt;
+		this.SYST_KIND_DVSN = systKindDvsn;
+
 		initVal();
 	}
 	public void initVal() {
-		TRAF_CLCT_CYCL = 0;
-		TFVL           = 0;
-		SPED           = 0;
-		AVRG_OCPY_RATE = 0;
-		AVRG_LNGT      = 0;
-		HDWY           = 0;
-		SPCE_OCPY_RATE = 0;
-		SPCE_AVRG_SPED = 0;
-		isValid        = false;
+		this.TRAF_CLCT_CYCL = 0;
+		this.TFVL           = 0;
+		this.SPED           = 0;
+		this.AVRG_OCPY_RATE = 0;
+		this.AVRG_LNGT      = 0;
+		this.HDWY           = 0;
+		this.SPCE_OCPY_RATE = 0;
+		this.SPCE_AVRG_SPED = 0;
+		this.isValid        = false;
 	}
 
 }

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

@@ -60,7 +60,7 @@ public class DbmsJobProcess extends AbstractDbmsJobProcess {
                     List<voVdsDtctStts> dtctSttsList = (List<voVdsDtctStts>)data.getData();
                     for (voVdsDtctStts vo : dtctSttsList) {
                         log.debug("DTCT_STTS: {}", vo.toString());
-                        this.vdsDtctMapper.updateVdsDtctStts(vo);       // 검지기 상태정보 업데이트
+                        //this.vdsDtctMapper.updateVdsDtctStts(vo);       // 검지기 상태정보 업데이트
                     }
                     dtctSttsList.clear();
                     break;
@@ -68,7 +68,7 @@ public class DbmsJobProcess extends AbstractDbmsJobProcess {
                     List<voVdsDtctVehClct> vehClctList = (List<voVdsDtctVehClct>)data.getData();
                     for (voVdsDtctVehClct vo : vehClctList) {
                         log.debug("VEH_CLCT: {}", vo.toString());
-                        this.vdsDtctMapper.insertVdsDtctVehClct(vo);     // 차량 수집정보 이력저장
+                        //this.vdsDtctMapper.insertVdsDtctVehClct(vo);     // 차량 수집정보 이력저장
                     }
                     vehClctList.clear();
                     break;

+ 24 - 24
src/main/java/com/its/vds/scheduler/SchedulerTask.java

@@ -45,31 +45,31 @@ public class SchedulerTask {
         }*/
     }
 
-    @Scheduled(cron = "10/30 * * * * *")    // 30초마다 요청(10초, 40초)
-    public void VdsTrafficRequestSchedule() {
-        if (!this.processConfig.isStartSchedule()) {
-            return;
-        }
-        Elapsed elapsed = new Elapsed();
-        log.info("VdsTrafficRequestSchedule: start. {}", Thread.currentThread().getName());
-        // 제어기 동기화 요청
-        // 교통데이터 요청
-        this.vdsCtlrService.requestTraffic();
-        log.info("VdsTrafficRequestSchedule: ..end. {} ms. {}", elapsed.milliSeconds(), Thread.currentThread().getName());
-    }
+//    @Scheduled(cron = "10/30 * * * * *")    // 30초마다 요청(10초, 40초)
+//    public void VdsTrafficRequestSchedule() {
+//        if (!this.processConfig.isStartSchedule()) {
+//            return;
+//        }
+//        Elapsed elapsed = new Elapsed();
+//        log.info("VdsTrafficRequestSchedule: start. {}", Thread.currentThread().getName());
+//        // 제어기 동기화 요청
+//        // 교통데이터 요청
+//        this.vdsCtlrService.requestTraffic();
+//        log.info("VdsTrafficRequestSchedule: ..end. {} ms. {}", elapsed.milliSeconds(), Thread.currentThread().getName());
+//    }
 
-    @Scheduled(cron = "15/30 * * * * *")    // 30초마다 요청(15초, 45초)
-    public void VdsVehicleRequestSchedule() {
-        if (!this.processConfig.isStartSchedule()) {
-            return;
-        }
-        Elapsed elapsed = new Elapsed();
-        // VDS 교통 데이터를 요청한 다음에 차량 정보를 요청한다.
-        // 제어기에서 동기화가 안되기 때문에 교통 데이터를 요청한 다음에 5초 후에 요청한다.
-        log.info("VdsVehicleRequestSchedule: start. {}", Thread.currentThread().getName());
-        this.vdsCtlrService.requestVehicle();
-        log.info("VdsVehicleRequestSchedule: ..end. {} ms. {}", elapsed.milliSeconds(), Thread.currentThread().getName());
-    }
+//    @Scheduled(cron = "15/30 * * * * *")    // 30초마다 요청(15초, 45초)
+//    public void VdsVehicleRequestSchedule() {
+//        if (!this.processConfig.isStartSchedule()) {
+//            return;
+//        }
+//        Elapsed elapsed = new Elapsed();
+//        // VDS 교통 데이터를 요청한 다음에 차량 정보를 요청한다.
+//        // 제어기에서 동기화가 안되기 때문에 교통 데이터를 요청한 다음에 5초 후에 요청한다.
+//        log.info("VdsVehicleRequestSchedule: start. {}", Thread.currentThread().getName());
+//        this.vdsCtlrService.requestVehicle();
+//        log.info("VdsVehicleRequestSchedule: ..end. {} ms. {}", elapsed.milliSeconds(), Thread.currentThread().getName());
+//    }
 
     @Scheduled(cron = "40 0/5 * * * *")    // 정주기 5분 40초에 스케쥴 실행
     public void StatisticsSchedule() {

+ 11 - 11
src/main/java/com/its/vds/service/StatisticsServices.java

@@ -90,16 +90,16 @@ public class StatisticsServices {
         MDC.clear();
     }
 
-    @Async("statisticsExecutor")
-    public void CRT_TB_VDS_DTCT_YY_STAT(String statDt, String fromDt, String toDt) {
-        MDC.put("id", logKey);
-        Elapsed elapsed = new Elapsed();
-        voStatisticsTime statTime = new voStatisticsTime(statDt, fromDt, toDt);
-        log.info("CRT_TB_VDS_DTCT_YY_STAT :: start. [{}], {}", statTime.toString(), Thread.currentThread().getName());
-        int result = this.statMapper.CRT_TB_VDS_DTCT_YY_STAT(statTime);
-        log.info("CRT_TB_VDS_DTCT_YY_STAT :: ..end. [{}], {} ms. {} EA. {}", statTime.toString(), elapsed.milliSeconds(), result, Thread.currentThread().getName());
-        MDC.remove(logKey);
-        MDC.clear();
-    }
+//    @Async("statisticsExecutor")
+//    public void CRT_TB_VDS_DTCT_YY_STAT(String statDt, String fromDt, String toDt) {
+//        MDC.put("id", logKey);
+//        Elapsed elapsed = new Elapsed();
+//        voStatisticsTime statTime = new voStatisticsTime(statDt, fromDt, toDt);
+//        log.info("CRT_TB_VDS_DTCT_YY_STAT :: start. [{}], {}", statTime.toString(), Thread.currentThread().getName());
+//        int result = this.statMapper.CRT_TB_VDS_DTCT_YY_STAT(statTime);
+//        log.info("CRT_TB_VDS_DTCT_YY_STAT :: ..end. [{}], {} ms. {} EA. {}", statTime.toString(), elapsed.milliSeconds(), result, Thread.currentThread().getName());
+//        MDC.remove(logKey);
+//        MDC.clear();
+//    }
 
 }

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

@@ -85,6 +85,9 @@ public class VdsCtlrService {
                     obj.getStts().setVDS_CTLR_NMBR(obj.getVDS_CTLR_NMBR());
                     obj.getStts().initStts(false);
 
+                    // 요청 패킷 초기화
+                    obj.initReqPacket();
+
                     AppRepository.getInstance().getCtlrMap().put(obj.getVDS_CTLR_NMBR(), obj);
                     AppRepository.getInstance().getCtlrIpMap().put(obj.getVDS_CTLR_IP(), obj);
                 }

+ 1 - 1
src/main/java/com/its/vds/xnettcp/handler/TcpServerIdleStateHandler.java

@@ -127,7 +127,7 @@ public class TcpServerIdleStateHandler extends IdleStateHandler {
                 obj.setDupChannel(null);
             }
             else {
-                obj.channelLogout();
+                obj.channelClosed();
 
                 // 클라이언트 연결 종료정보를 운영단말로 전송한다.
                 CenterCommResponseService centerCommResponseService = (CenterCommResponseService)AppUtils.getBean(CenterCommResponseService.class);

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

@@ -0,0 +1,152 @@
+package com.its.vds.xnettcp.vds;
+
+import com.its.vds.config.LocalCommConfig;
+import com.its.vds.entity.TbVdsCtlr;
+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.protocol.VdsProtocol;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.*;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.handler.logging.LogLevel;
+import io.netty.handler.logging.LoggingHandler;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@Getter
+@Setter
+@RequiredArgsConstructor
+public class VdsTcpClient implements Callable<Object> {
+
+    private final TbVdsCtlr controller;
+    private final LocalCommConfig commConfig;
+    private final VdsTcpClientBootstrapFactory bootstrapFactory;
+
+    private Bootstrap bootstrap = null;
+    private ChannelFuture channelFuture = null;
+    private String ipAddress;
+    private int port;
+
+    @Override
+    public Object call() {
+
+        this.ipAddress = this.controller.getVDS_CTLR_IP();
+        this.port = this.controller.getVDS_CTLR_PORT();
+
+        log.info("VdsTcpClient start: {}, {}", this.ipAddress, this.port);
+        if (this.bootstrap == null) {
+            this.bootstrap = this.bootstrapFactory.createBootstrap();
+            this.bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, this.commConfig.getConnectTimeout() * 1000);
+            this.bootstrap.handler(new ChannelInitializer<SocketChannel>() {
+                // VDS 전송 요청을 먼저하고 데이터를 수신한다.
+                // 핸들러가 실행되는 순서는 추가된 순서에 의해 결정된다.(Inbound: head=>tail, Outbound: tail=>head, name2ctx)
+                @Override
+                public void initChannel(SocketChannel ch) {
+                    if (commConfig.isCommLogging()) {
+                        //io.netty.handler.logging.LoggingHandler
+                        //ch.pipeline().addLast(new LoggingHandler(LogLevel.WARN));
+                    }
+                    else {
+                        ch.pipeline().addLast(new LoggingHandler(LogLevel.ERROR));
+                    }
+                    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("vdsClientEncoder",        new VdsTcpClientEncoder());            // Encoding handler
+                }
+            });
+        }
+
+        log.info("VDS Controller try connect: {}, {}", this.ipAddress, this.port);
+        if (this.channelFuture != null && this.channelFuture.channel() != null) {
+            this.channelFuture.channel().close();
+            this.channelFuture = null;
+        }
+        this.channelFuture = this.bootstrap.connect(new InetSocketAddress(this.ipAddress, this.port));
+
+        // 연결 리스너 추가
+        this.channelFuture.addListener(new ChannelFutureListener() {
+            @Override public void operationComplete(ChannelFuture future) {
+                if (future.isSuccess()) {
+                    log.info("VDS Controller Channel open");
+                    channelOpen(future.channel());
+                } else {
+                    log.error("VDS Controller connectFailed: {}", future.cause().toString());
+                }
+            }
+        });
+
+        // 연결 종료 리스너 추가
+        this.channelFuture.channel().closeFuture().addListener(new ChannelFutureListener() {
+            @Override public void operationComplete(ChannelFuture future) {
+                channelClosed(future.channel());
+            }
+        });
+
+        return null;
+    }
+
+    /**
+     * 연결 성공시 처리 이벤트
+     * @param channel
+     */
+    protected void channelOpen(Channel channel) {
+        log.info("VDS Controller connected: channel {}", channel);
+        this.controller.channelOpen(channel);
+
+        TbVdsCtlr obj = this.controller;
+
+        // 온도정보 요청
+        ByteBuffer sendBuff;
+        sendBuff = obj.getReqSynchronize().getByteBuffer();
+        ChannelFuture f = obj.getChannel().writeAndFlush(sendBuff);
+        f.awaitUninterruptibly();
+        if (f.isDone() || f.isSuccess()) {
+            log.info("SEND_0: [{}], vds_Synchronization: {} sendBytes. [{}]", obj.getVDS_CTLR_IP(), sendBuff.array().length, obj.getVDS_CTLR_ID());
+        } else {
+            log.error("SEND_0: [{}], vds_Synchronization: {} sendBytes, Failed. [{}]", obj.getVDS_CTLR_IP(), sendBuff.array().length, obj.getVDS_CTLR_ID());
+        }
+        VdsProtocol.sleep(500);
+
+        ByteBuffer sendBuff_ = obj.getReqData().getByteBuffer();
+        ChannelFuture f_ = obj.getChannel().writeAndFlush(sendBuff_);
+        f_.awaitUninterruptibly();
+        if (f_.isDone() || f_.isSuccess()) {
+            log.info("SEND_0: [{}], vds_Data: {} sendBytes. [{}]", obj.getVDS_CTLR_IP(), sendBuff_.array().length, obj.getVDS_CTLR_ID());
+        } else {
+            log.error("SEND_0: [{}], vds_Data: {} sendBytes, Failed. [{}]", obj.getVDS_CTLR_IP(), sendBuff_.array().length, obj.getVDS_CTLR_ID());
+        }
+        VdsProtocol.sleep(500);
+
+        ByteBuffer sendBuff__ = obj.getReqTemperature().getByteBuffer();
+        ChannelFuture f__ = obj.getChannel().writeAndFlush(sendBuff__);
+        f__.awaitUninterruptibly();
+        if (f__.isDone() || f__.isSuccess()) {
+            log.info("SEND_0: [{}], vds_Temperature: {} sendBytes. [{}]", obj.getVDS_CTLR_IP(), sendBuff__.array().length, obj.getVDS_CTLR_ID());
+        } else {
+            log.error("SEND_0: [{}], vds_Temperature: {} sendBytes, Failed. [{}]", obj.getVDS_CTLR_IP(), sendBuff__.array().length, obj.getVDS_CTLR_ID());
+        }
+    }
+
+    /**
+     * 연결 종료시 처리 이벤트
+     * @param channel
+     */
+    protected synchronized void channelClosed(Channel channel) {
+        log.error("VDS Controller closed: channel {}", channel);
+        this.controller.channelClosed();
+        channel.close();
+        channel.eventLoop().schedule(this, this.commConfig.getRetrySeconds(), TimeUnit.SECONDS);
+    }
+
+}

+ 68 - 0
src/main/java/com/its/vds/xnettcp/vds/VdsTcpClientBootstrapFactory.java

@@ -0,0 +1,68 @@
+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 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;
+
+@Slf4j
+@RequiredArgsConstructor
+public class VdsTcpClientBootstrapFactory {
+
+    private final int workerThread;
+    private final int connectTimeout;
+    private final boolean isLogging;
+    private EventLoopGroup nioEventLoopGroup = null;
+
+    public Bootstrap createBootstrap() {
+        if (this.nioEventLoopGroup == null) {
+            this.nioEventLoopGroup = NettyUtils.newEventLoopGroup(this.workerThread, "vdsEventGroup");//new NioEventLoopGroup(this.workerThread);  //EpollEventLoopGroup
+        }
+        Bootstrap bootstrap = new Bootstrap();
+        bootstrap.group(this.nioEventLoopGroup);
+
+        bootstrap.channel(NioSocketChannel.class);
+        bootstrap.option(ChannelOption.AUTO_READ, true);
+        bootstrap.option(ChannelOption.TCP_NODELAY, true);
+        bootstrap.option(ChannelOption.SO_KEEPALIVE, true);//false);
+        bootstrap.option(ChannelOption.SO_RCVBUF, 8192);
+        bootstrap.option(ChannelOption.SO_SNDBUF, 8192);
+        bootstrap.option(ChannelOption.SO_KEEPALIVE, false);
+        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());     // Packet Inbound handler
+                ch.pipeline().addLast("vdsClientEncoder",        new VdsTcpClientEncoder());            // Encoding handler
+            }
+        });
+
+        return bootstrap;
+    }
+
+    public EventLoopGroup getEventLoopGroup() {
+        return this.nioEventLoopGroup;
+    }
+    public void addChannelFuture(ChannelFuture future) {
+        //this.channelFutures.add(future);
+    }
+}

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

@@ -0,0 +1,71 @@
+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 lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+@Slf4j
+@Getter
+@RequiredArgsConstructor
+@Service
+public class VdsTcpClientCommService {
+
+    private final LocalCommConfig commConfig;
+    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());
+    }
+
+    public void run() {
+        log.info("VdsTcpClientCommService.run: Start.");
+
+        /**
+         * 제어기접속
+         */
+        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);
+                this.clientTasks.add(vdsClient);
+            }
+        }
+
+        try {
+            List<Future<Object>> futures = this.executorService.invokeAll(this.clientTasks);
+            log.info("VdsTcpClientCommService.run: futures, {} EA.", (long)futures.size());
+        } catch(InterruptedException e) {
+            log.error("run: Exception: InterruptedException");
+        }
+
+        log.info("VdsTcpClientCommService.run: ..End.");
+    }
+
+    public void shutdown() {
+        for (Map.Entry<String, TbVdsCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
+            TbVdsCtlr obj = e.getValue();
+            if (obj.getChannel() != null) {
+                obj.getChannel().close();
+            }
+        }
+
+        this.bootstrapFactory.getEventLoopGroup().shutdownGracefully();
+        log.error("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+    }
+}

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

@@ -0,0 +1,114 @@
+package com.its.vds.xnettcp.vds.codec;
+
+import com.its.app.utils.NettyUtils;
+import com.its.vds.entity.TbVdsCtlr;
+import com.its.vds.global.AppRepository;
+import com.its.vds.xnettcp.handler.TcpServerIdleStateHandler;
+import com.its.vds.xnettcp.protocol.VDS_RES_BODY;
+import com.its.vds.xnettcp.protocol.VDS_RES_HEAD;
+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;
+import org.slf4j.MDC;
+
+import java.util.List;
+
+@Slf4j
+public class VdsTcpClientDecoder extends ByteToMessageDecoder {
+
+    @Override
+    protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> list) {
+
+        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());
+        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);
+            TcpServerIdleStateHandler.disconnectChannel(channel);
+            return;
+        }
+
+        MDC.put("id", obj.getLogKey());
+
+        if (!channel.isOpen() || !channel.isActive()) {
+            log.error("TcpServerDecoder.decode: {}, isOpen: {}, isActive: {}. [{}]", ipAddress, channel.isOpen(), channel.isActive(), obj.getLogKey());
+            TcpServerIdleStateHandler.disconnectChannel(channel);
+            return;
+        }
+
+        int readableBytes = byteBuf.readableBytes();
+        log.info("RECV_0: [{}]. ReadableBytes: {} Bytes, ReaderIndex: {}", ipAddress, readableBytes, byteBuf.readerIndex());
+        if (readableBytes == 0) {
+            log.error("RECV: {}. byteBuf.readableBytes() == 0. [{]{}]", ipAddress, obj.getLogKey());
+            return;
+        }
+
+//        if (this.applicationConfig.getTcpRecvDump().equals("true")) {
+//            byte[] debugBytes = new byte[byteBuf.readableBytes()];
+//            byteBuf.getBytes(byteBuf.readerIndex(), debugBytes);
+//            log.info("RECV: [{}], {} Bytes. {}", ipAddress, debugBytes.length, SysUtils.byteArrayToHex(debugBytes));
+//        }
+
+        int packetCnt = 0;
+        int headLength = VDS_RES_HEAD.VDS_RES_HEADER_SIZE;
+        int bodyLength = 0;
+        int remainLength = 0;
+        while (readableBytes >= headLength) {
+            byteBuf.markReaderIndex();
+            byte[] headBuffer = new byte[headLength];
+            byteBuf.readBytes(headBuffer);
+            try {
+                // 헤더 데이터 먼저 읽는다.
+                VDS_RES_HEAD head = new VDS_RES_HEAD(headBuffer);
+                bodyLength = head.getBodyLength();
+                remainLength = readableBytes - headLength;
+
+                if (bodyLength > remainLength) {
+                    // 패킷을 한번에 수신하지 못하였다.
+                    log.warn("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();
+
+                // 한 패킷이 완성되었음.
+                VDS_RES_BODY body = new VDS_RES_BODY(head, bodyBuffer);
+                list.add(body);
+
+                readableBytes = byteBuf.readableBytes();
+                packetCnt++;
+                log.info("RECV_{}: [{}]. ReadableBytes: {} Bytes, ReaderIndex: {}, ===> packet encoding ok.", packetCnt, ipAddress, readableBytes, byteBuf.readerIndex());
+            }
+            catch(Exception e) {
+                log.error("TcpServerDecoder.decode: RECV: {}. Exception Error: will be closed: {}. [{}]", ipAddress, e.toString(), obj.getLogKey());
+                TcpServerIdleStateHandler.disconnectChannel(channel);
+            }
+        }
+        byteBuf.resetReaderIndex();
+        MDC.remove(obj.getLogKey());
+        MDC.clear();
+    }
+}

+ 28 - 0
src/main/java/com/its/vds/xnettcp/vds/codec/VdsTcpClientEncoder.java

@@ -0,0 +1,28 @@
+package com.its.vds.xnettcp.vds.codec;
+
+import com.its.app.utils.NettyUtils;
+import com.its.app.utils.SysUtils;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToByteEncoder;
+import lombok.extern.slf4j.Slf4j;
+
+import java.nio.ByteBuffer;
+
+@Slf4j
+@ChannelHandler.Sharable
+public class VdsTcpClientEncoder extends MessageToByteEncoder<Object> {
+
+    @Override
+    protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf outByteBuf) {
+
+        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());
+        //Channel channel = ctx.channel();
+
+        ByteBuffer buffer = (ByteBuffer)msg;
+        byte[] sendBytes = buffer.array();
+        outByteBuf.writeBytes(sendBytes);
+        log.info("SEND: [{}], {} Bytes. {}", ipAddress, sendBytes.length, SysUtils.byteArrayToHex(sendBytes));
+    }
+}

+ 93 - 0
src/main/java/com/its/vds/xnettcp/vds/handler/VdsTcpClientIdleHandler.java

@@ -0,0 +1,93 @@
+package com.its.vds.xnettcp.vds.handler;
+
+import com.its.app.utils.NettyUtils;
+import com.its.vds.entity.TbVdsCtlr;
+import com.its.vds.global.AppRepository;
+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.IdleState;
+import io.netty.handler.timeout.IdleStateEvent;
+import io.netty.handler.timeout.IdleStateHandler;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
+
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@ChannelHandler.Sharable
+public class VdsTcpClientIdleHandler extends IdleStateHandler {
+
+    public VdsTcpClientIdleHandler(long readerIdleTime, long writerIdleTime, long allIdleTime, TimeUnit unit) {
+        super(readerIdleTime, writerIdleTime, allIdleTime, unit);
+    }
+
+    @Override
+    protected void channelIdle(ChannelHandlerContext ctx, IdleStateEvent evt) {
+        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());
+        log.warn("channelIdle: {}", ipAddress);
+
+        TbVdsCtlr obj = AppRepository.getInstance().getCtlrIpMap().get(ipAddress);
+        if (obj != null) {
+            MDC.put("id", obj.getLogKey());
+        }
+        if (evt.state() == IdleState.ALL_IDLE) {
+            log.error("VdsTcpClientIdleHandler.------channelIdle: [{}], ALL_IDLE", ipAddress);
+            VdsTcpClientIdleHandler.disconnectChannel(ctx.channel());
+        }
+        else if (evt.state() == IdleState.READER_IDLE) {
+            log.warn("VdsTcpClientIdleHandler.------channelIdle: READER_IDLE, [{}]", ipAddress);
+            VdsTcpClientIdleHandler.disconnectChannel(ctx.channel());
+        }
+        else if (evt.state() == IdleState.WRITER_IDLE) {
+            log.warn("VdsTcpClientIdleHandler.------channelIdle: WRITER_IDLE, [{}]", ipAddress);
+        }
+
+        if (obj != null) {
+            MDC.remove(obj.getLogKey());
+            MDC.clear();
+        }
+    }
+
+    /*
+     *  클라이언트와의 연결 종료를 위해 호출하는 함수
+     */
+    public static void disconnectChannel(Channel channel) {
+        // 로그인 하지 않은 또는 비정상 접속 네트워크 세션 종료(로그인 처리를 수행하지 않은 세션에 대한 종료)
+        String ipAddress = NettyUtils.getRemoteIpAddress(channel);
+        TbVdsCtlr obj = AppRepository.getInstance().getCtlrIpMap().get(ipAddress);
+        if (obj != null) {
+            MDC.put("id", obj.getLogKey());
+        }
+        log.error("VdsTcpClientIdleHandler.disconnectChannel: [{}]", ipAddress);
+        if (!channel.isActive()) {
+            log.error("VdsTcpClientIdleHandler.disconnectChannel: [{}], channel already closed.", ipAddress);
+        }
+        try {
+            //////////////////////////////////
+            // 클라이언트와의 연결을 종료한다.
+            //////////////////////////////////
+            channel.flush();
+            ChannelFuture f = channel.disconnect().awaitUninterruptibly();
+            if (!f.isDone() || !f.isSuccess()) {
+                log.error("VdsTcpClientIdleHandler.disconnectChannel: [{}], isDone: {}, isSuccess: {}", ipAddress, f.isDone(), f.isSuccess());
+            }
+        }
+        catch(Exception e) {
+        }
+
+        if (obj != null) {
+            MDC.remove(obj.getLogKey());
+            MDC.clear();
+        }
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());
+        log.error("exceptionCaught: {}, {}", ipAddress, cause.getMessage());
+
+        ctx.channel().close();
+    }
+}

+ 17 - 0
src/main/java/com/its/vds/xnettcp/vds/handler/VdsTcpClientInboundHandler.java

@@ -0,0 +1,17 @@
+package com.its.vds.xnettcp.vds.handler;
+
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@ChannelHandler.Sharable
+public class VdsTcpClientInboundHandler extends SimpleChannelInboundHandler<Object> {
+
+    @Override
+    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object msg) {
+        log.info("channelRead0: {}", msg);
+    }
+
+}

+ 20 - 0
src/main/java/com/its/vds/xnettcp/vds/handler/VdsTcpClientOutboundHandler.java

@@ -0,0 +1,20 @@
+package com.its.vds.xnettcp.vds.handler;
+
+import io.netty.channel.*;
+
+public class VdsTcpClientOutboundHandler extends ChannelOutboundHandlerAdapter {
+
+    @Override
+    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
+        promise.addListener(new ChannelFutureListener() {
+            @Override
+            public void operationComplete(ChannelFuture f) {
+                if (!f.isSuccess()) {
+                    f.cause().printStackTrace();
+                    f.channel().close();
+                }
+            }
+        });
+    }
+
+}

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

@@ -0,0 +1,137 @@
+package com.its.vds.xnettcp.vds.protocol;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.nio.ByteOrder;
+
+@Slf4j
+public class VdsProtocol {
+
+    /**
+     * 요청 프레임 형식
+     */
+//    DLE/STX	    1BYTE/1BYTE	        [FRAME HEADER]  메시지 시작 부분 	    DLE = 10H STX = 02H
+//    ADDRESS	    4 BYTE	Controller  Station Number
+//                                      - BYTE 1&2 : Group Number
+//		                                - BYTE 3&4 : Controller Number
+//                                      (DLE stuffing is conformed to BSC protocol rule.)
+//    OP-Code	    1 BYTE	            [COMMAND/REPLY MESSAGE TYPE]
+//                                      (DLE stuffing is conformed to BSC protocol rule.)
+//    DATA          FILED		        OP-Code 의 종류별로 상이함
+//                                      (DLE stuffing is conformed to BSC protocol rule.)
+//    DLE/ETX	    1BYTE/1BYTE	        [FRAME TERMINATOR]  메시지의 끝부분	    DLE = 10H ETX = 03H
+//    CRC-16	    2 BYTE	            Ieee's Standard Cyclic Redundancy Check Code - DLE Stuffing 전 데이터에 적용을 기준으로 함.
+//    Data Field	0 ~ 254 BYTE	    OP-Code 별로 유동적임
+
+    /**
+     * 응답 프레임 형식
+     */
+//    DLE/STX	    1BYTE/1BYTE	        [FRAME HEADER]  메시지 시작 부분 	    DLE = 10H STX = 02H
+//    ADDRESS	    4 BYTE	Controller  Station Number
+//                                      - BYTE 1&2 : Group Number
+//		                                - BYTE 3&4 : Controller Number
+//                                      (DLE stuffing is conformed to BSC protocol rule.)
+//    OP-Code	    1 BYTE	            [COMMAND/REPLY MESSAGE TYPE]
+//                                      (DLE stuffing is conformed to BSC protocol rule.)
+//    STATUS        2 BYTE              --------------------------------------------------------------------------------------------
+//    DATA          FILED		        OP-Code 의 종류별로 상이함
+//                                      (DLE stuffing is conformed to BSC protocol rule.)
+//    DLE/ETX	    1BYTE/1BYTE	        [FRAME TERMINATOR]  메시지의 끝부분	    DLE = 10H ETX = 03H
+//    CRC-16	    2 BYTE	            Ieee's Standard Cyclic Redundancy Check Code - DLE Stuffing 전 데이터에 적용을 기준으로 함.
+//    Data Field	0 ~ 254 BYTE	    OP-Code 별로 유동적임
+
+    public static final ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;
+
+    public static final byte vds_DLE    = (byte)0x10;
+    public static final byte vds_STX    = (byte)0x02;
+    public static final byte vds_ETX    = (byte)0x03;
+
+    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] - -
+    public static final byte vds_Data               = (byte)0x04;   // VDS 데이터 요구 (Data Request) 데이터 요구 #4[0x04] 센터→로컬 교통data(교통량,점유율,차량길이,속도)
+    public static final byte vds_Speed              = (byte)0x05;   // VDS 데이터 요구 (Data Request) 속도 데이터 요구 #5[0x05] 센터→로컬 특정차로 속도data
+    public static final byte vds_Length             = (byte)0x06;   // VDS 데이터 요구 (Data Request) 차량 길이 데이터 요구 #6[0x06] 센터→로컬 특정차로 차량길이data
+    public static final byte vds_Traffic            = (byte)0x07;   // VDS 데이터 요구 (Data Request) 누적 교통량 데이터 요구 #7[0x07] 센터→로컬 교통량data
+    public static final byte vds_Image              = (byte)0x16;   // VDS 데이터 요구 (Data Request) 화상이미지 요구 #22[0x16] 센터→로컬 이미지data
+    public static final byte vds_Vehicle            = (byte)0x17;   // VDS 데이터 요구 (Data Request) 개별차량 데이터 요구 #23[0x17] 센터→로컬 개별차량 data
+    public static final byte vds_Reserved03         = (byte)0x09;   // 제어기 상태 장래사용 #9[0x09] - -
+    public static final byte vds_Reserved04         = (byte)0x0A;   // 제어기 상태 장래사용 #10[0x0A] - -
+    public static final byte vds_Validation         = (byte)0x0B;   // 제어기 상태 제어기 Validation #11[0x0B] 센터→로컬 H/W check 결과
+    public static final byte vds_Reset              = (byte)0x0C;   // 제어기 상태 제어기 Reset #12[0x0C] 센터→로컬 ACK/NAK
+    public static final byte vds_Initialize         = (byte)0x0D;   // 제어기 상태 제어기 Initialize #13[0x0D] 센터→로컬 ACK/NAK
+    public static final byte vds_RTC                = (byte)0x18;   // 제어기 상태 RTC 변경 #24[0x18] 센터→로컬 ACK/NAK
+    public static final byte vds_Temperature        = (byte)0x1E;   // 제어기 상태 함체온도 및 입출력전압 요청 #30[0x1E] 센터→로컬 함체온도/입출력전압
+    public static final byte vds_Downloading        = (byte)0x0E;   // 파라미터 Download 파라미터 Downloading #14[0x0E] 센터→로컬 ACK/NAK
+    public static final byte vds_Uploading          = (byte)0x0F;   // 파라미터 Upload 파라미터 Uploading #15[0x0F] 센터→로컬 파라미터값
+    public static final byte vds_Online             = (byte)0x11;   // 온라인 상태조사 온라인 상태조사 #17[0x11] 센터→로컬 Passed Time
+    public static final byte vds_CheckMemory        = (byte)0x12;   // 원격진단 메모리 Check #18[0x12] 센터→로컬 ACK/NAK
+    public static final byte vds_CheckEcho          = (byte)0x13;   // 원격진단 Echo Check #19[0x13] 센터→로컬 Echo메시지
+    public static final byte vds_CheckSeq           = (byte)0x14;   // 원격진단 순번 Check #20[0x14] 센터→로컬 수치처리 결과값
+    public static final byte vds_Version            = (byte)0x15;   // 원격진단 VDS Version 요청 #21[0x15] 센터→로컬 version정보
+    public static final byte vds_Usage              = (byte)0x19;   // 기타 사용/사용불가 설정 #25[0x19] 운영단말→수집서버 사용여부 설정결과값
+    public static final byte vds_SetRunTemp         = (byte)0x20;   // 기타 Fan/Heater 동작온도설정 #26[0x20] 센터→로컬 ACK/NAK
+
+    /**
+     * VDS Protocol CRC16
+     */
+    private static final int crc16_arc[] = {
+            0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
+            0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
+            0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
+            0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
+            0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
+            0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
+            0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
+            0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
+            0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
+            0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
+            0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
+            0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
+            0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
+            0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
+            0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
+            0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
+            0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
+            0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
+            0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
+            0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
+            0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
+            0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
+            0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
+            0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
+            0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
+            0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
+            0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
+            0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
+            0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
+            0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
+            0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
+            0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
+    };
+
+    /**
+     * VDS CRC16-ARC(https://crccalc.com/)
+     * @param data
+     * @param start
+     * @param length
+     * @return
+     */
+    public static short getCRC16ARC(byte[] data, int start, int length) {
+        int crc = 0x0000;
+        for (int ii = start; ii < (start+length); ii++) {
+            int b = data[ii];
+            crc = (crc >> 8) ^ crc16_arc[(crc ^ data[ii]) & 0xff];
+        }
+        //log.error("{}", Integer.toHexString(crc));
+        return (short)(crc & 0x0000FFFF);
+    }
+
+    public static void sleep(long milliSeconds) {
+        try {
+            Thread.sleep(milliSeconds);
+        } catch (InterruptedException e) {
+            log.error("sleep: InterruptedException");
+        }
+    }
+}

+ 11 - 0
src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqData.java

@@ -0,0 +1,11 @@
+package com.its.vds.xnettcp.vds.protocol;
+
+public class VdsReqData extends VdsReqFramePacket {
+
+    private byte frameNo;
+
+    public VdsReqData(short groupNo, short controllerNo) {
+        super(groupNo, controllerNo, VdsProtocol.vds_Data);
+    }
+
+}

+ 48 - 0
src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqFrameHead.java

@@ -0,0 +1,48 @@
+package com.its.vds.xnettcp.vds.protocol;
+
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.nio.ByteBuffer;
+
+@Slf4j
+@Getter
+public class VdsReqFrameHead {
+
+    public static int SIZE = 7;
+
+    private final byte dle = VdsProtocol.vds_DLE;
+    private final byte stx = VdsProtocol.vds_STX;
+
+    private short groupNo;
+    private short controllerNo;
+    private byte  opCode;
+
+    public VdsReqFrameHead() {
+        this.groupNo = 0;
+        this.controllerNo = 0;
+        this.opCode = 0;
+    }
+
+    public VdsReqFrameHead(short groupNo, short controllerNo, byte opCode) {
+        this.groupNo = groupNo;
+        this.controllerNo = controllerNo;
+        this.opCode = opCode;
+    }
+
+    public VdsReqFrameHead(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();
+            this.opCode = byteBuffer.get();
+        }
+        else {
+            log.error("VdsReqFrameHead: create failed, headBytes error");
+        }
+    }
+
+}

+ 77 - 0
src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqFramePacket.java

@@ -0,0 +1,77 @@
+package com.its.vds.xnettcp.vds.protocol;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public class VdsReqFramePacket {
+
+    private ByteOrder byteOrder = VdsProtocol.byteOrder;
+
+    protected VdsReqFrameHead head;
+    protected byte[]          body;
+    protected VdsReqFrameTail tail;
+
+    public VdsReqFramePacket() {
+        this.head = new VdsReqFrameHead();
+        this.body = null;
+        this.tail = new VdsReqFrameTail();
+    }
+
+    public VdsReqFramePacket(short groupNo, short controllerNo, byte opCode) {
+        this.head = new VdsReqFrameHead(groupNo, controllerNo, opCode);
+        this.body = null;
+        this.tail = new VdsReqFrameTail();
+    }
+
+    public VdsReqFramePacket(VdsReqFrameHead head, byte[] body, VdsReqFrameTail tail) {
+        this.head = head;
+        this.body = body;
+        this.tail = tail;
+    }
+
+    public void setByteOrder(ByteOrder byteOrder) {
+        this.byteOrder = byteOrder;
+    }
+
+    /**
+     * 요청 패킷을 ByteBuffer 로 변경하여 리턴
+     * @return
+     */
+    public ByteBuffer getByteBuffer() {
+        int bodySize = 0;
+        if (this.body != null) {
+            bodySize = this.body.length;
+        }
+        ByteBuffer byteBuffer = ByteBuffer.allocate(VdsReqFrameHead.SIZE + bodySize + VdsReqFrameTail.SIZE);
+        byteBuffer.order(this.byteOrder);
+
+        // HEAD
+        byteBuffer.put(this.head.getDle());
+        byteBuffer.put(this.head.getStx());
+        byteBuffer.putShort(this.head.getGroupNo());
+        byteBuffer.putShort(this.head.getControllerNo());
+        byteBuffer.put(this.head.getOpCode());
+
+        // BODY
+        if (bodySize > 0) {
+            byteBuffer.put(this.body);
+        }
+
+        // TAIL
+        byteBuffer.put(this.tail.getDle());
+        byteBuffer.put(this.tail.getEtx());
+        byteBuffer.putShort(this.tail.getCrc());
+
+        return byteBuffer;
+    }
+
+    public void makeCRC() {
+        ByteBuffer byteBuffer = getByteBuffer();
+        short crc = VdsProtocol.getCRC16ARC(byteBuffer.array(), 2, byteBuffer.array().length - 6);
+        //byte crc1 = (byte)((crc >> 8) & 0xFF);
+        //byte crc2 = (byte)((crc     ) & 0xFF);
+        //byteBuffer.put(crc1); // CRC1
+        //byteBuffer.put(crc2); // CRC2
+        this.tail.setCrc(crc);
+    }
+}

+ 21 - 0
src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqFrameTail.java

@@ -0,0 +1,21 @@
+package com.its.vds.xnettcp.vds.protocol;
+
+import lombok.Getter;
+
+@Getter
+public class VdsReqFrameTail {
+
+    public static int SIZE = 4;
+
+    private final byte dle = VdsProtocol.vds_DLE;
+    private final byte etx = VdsProtocol.vds_ETX;
+    private short crc;
+
+    public VdsReqFrameTail() {
+        this.crc = 0;
+    }
+
+    public void setCrc(short crc) {
+        this.crc = crc;
+    }
+}

+ 17 - 0
src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqSynchronize.java

@@ -0,0 +1,17 @@
+package com.its.vds.xnettcp.vds.protocol;
+
+public class VdsReqSynchronize extends VdsReqFramePacket {
+
+    private byte frameNo;
+
+    public VdsReqSynchronize(short groupNo, short controllerNo) {
+        super(groupNo, controllerNo, VdsProtocol.vds_Synchronization);
+        this.body = new byte[1];
+        setFrameNo((byte)0x01);
+    }
+
+    public void setFrameNo(byte frameNo) {
+        this.frameNo = frameNo;
+        this.body[0] = this.frameNo;
+    }
+}

+ 11 - 0
src/main/java/com/its/vds/xnettcp/vds/protocol/VdsReqTemperature.java

@@ -0,0 +1,11 @@
+package com.its.vds.xnettcp.vds.protocol;
+
+public class VdsReqTemperature extends VdsReqFramePacket {
+
+    private byte frameNo;
+
+    public VdsReqTemperature(short groupNo, short controllerNo) {
+        super(groupNo, controllerNo, VdsProtocol.vds_Temperature);
+    }
+
+}

+ 15 - 0
src/main/java/com/its/vds/xnettcp/vds/protocol/VdsResFrameHead.java

@@ -0,0 +1,15 @@
+package com.its.vds.xnettcp.vds.protocol;
+
+import lombok.Getter;
+
+@Getter
+public class VdsResFrameHead {
+
+    protected byte  dle;
+    protected byte  stx;
+    protected short groupNo;
+    protected short controllerNo;
+    protected byte  opCode;
+    protected byte  status1;
+    protected byte  status2;
+}

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

@@ -0,0 +1,8 @@
+package com.its.vds.xnettcp.vds.protocol;
+
+public class VdsResFramePacket {
+
+    VdsResFrameHead head;
+    byte[]          body;
+    VdsResFrameTail tail;
+}

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

@@ -0,0 +1,11 @@
+package com.its.vds.xnettcp.vds.protocol;
+
+import lombok.Getter;
+
+@Getter
+public class VdsResFrameTail {
+
+    protected byte  dle;
+    protected byte  etx;
+    protected short crc;
+}

+ 8 - 0
src/main/java/com/its/vds/xnettcp/vds/protocol/VdsUtils.java

@@ -0,0 +1,8 @@
+package com.its.vds.xnettcp.vds.protocol;
+
+public class VdsUtils {
+
+    public static byte getFrameNo(int cycle, int min, int sec) {
+        return (byte)((min*60 + sec) / cycle + 1);
+    }
+}

+ 8 - 0
src/main/resources/application.yml

@@ -5,12 +5,20 @@ application:
     history: false
     user-id: admin
     user-pswd: 1234
+
   thread-pool:
+
   facility-manager:
     enabled: true
     ip-addr: 172.16.12.25
     send-port: 5701
     recv-port: 5202
+
+  local-comm:
+    comm-logging: true
+    retry-seconds: 10
+    connect-timeout: 5
+
   center-comm:
     listen-port: 9901
 

+ 0 - 0
src/main/resources/logback-spring.xml → src/main/resources/logback-spring.xmlx


+ 2 - 1
src/main/resources/mybatis/mapper/VdsCtlrMapper.xml

@@ -126,7 +126,8 @@
 				  #{stts.UPDT_DT},
 				  #{stts.VDS_CTLR_NMBR},
 				  #{stts.CMNC_STTS_CD},
-				  #{stts.CBOX_DOOR_STTS_CD},
+                  #{stts.PRNT_PWER_STTS_CD},
+                  #{stts.CBOX_DOOR_STTS_CD},
 				  #{stts.FAN_STTS_CD},
 				  #{stts.HETR_STTS_CD},
 				  #{stts.SUB_CTLR_VAL},

+ 104 - 112
src/main/resources/mybatis/mapper/VdsDtctMapper.xml

@@ -30,81 +30,79 @@
     ]]>
     </select>
 
-    <update id="updateVdsDtctStts" parameterType="com.its.vds.entity.voVdsDtctStts">
-    <![CDATA[
-		MERGE INTO TB_VDS_DTCT_STTS L                   
-		USING (SELECT #{stts.VDS_DTCT_NMBR} AS VDS_DTCT_NMBR,            
-		              #{stts.UPDT_DT} 	 	AS UPDT_DT,                  
-		              #{stts.DTCT_STTS} 	AS DTCT_STTS                 
-		         FROM DUAL) M                           
-		        ON (L.VDS_DTCT_NMBR = M.VDS_DTCT_NMBR)  
-		WHEN MATCHED THEN                               
-		   UPDATE SET L.UPDT_DT   = M.UPDT_DT,          
-		              L.DTCT_STTS = M.DTCT_STTS         
-		WHEN NOT MATCHED THEN                           
-		   INSERT (
-		           VDS_DTCT_NMBR,                       
-		           UPDT_DT,                             
-		           DTCT_STTS 
-		          )                          
-		   VALUES (
-		           M.VDS_DTCT_NMBR,                     
-		           M.UPDT_DT,                           
-		           M.DTCT_STTS 
-		          )                        
-    ]]>
-    </update>
+    <!-- 용인시는 검지기상태정보 생성하지 않음  -->
+<!--    <update id="updateVdsDtctStts" parameterType="com.its.vds.entity.voVdsDtctStts">-->
+<!--    <![CDATA[-->
+<!--		MERGE INTO TB_VDS_DTCT_STTS L                   -->
+<!--		USING (SELECT #{stts.VDS_DTCT_NMBR} AS VDS_DTCT_NMBR,            -->
+<!--		              #{stts.UPDT_DT} 	 	AS UPDT_DT,                  -->
+<!--		              #{stts.DTCT_STTS} 	AS DTCT_STTS                 -->
+<!--		         FROM DUAL) M                           -->
+<!--		        ON (L.VDS_DTCT_NMBR = M.VDS_DTCT_NMBR)  -->
+<!--		WHEN MATCHED THEN                               -->
+<!--		   UPDATE SET L.UPDT_DT   = M.UPDT_DT,          -->
+<!--		              L.DTCT_STTS = M.DTCT_STTS         -->
+<!--		WHEN NOT MATCHED THEN                           -->
+<!--		   INSERT (-->
+<!--		           VDS_DTCT_NMBR,                       -->
+<!--		           UPDT_DT,                             -->
+<!--		           DTCT_STTS -->
+<!--		          )                          -->
+<!--		   VALUES (-->
+<!--		           M.VDS_DTCT_NMBR,                     -->
+<!--		           M.UPDT_DT,                           -->
+<!--		           M.DTCT_STTS -->
+<!--		          )                        -->
+<!--    ]]>-->
+<!--    </update>-->
 
-    <insert id="insertVdsDtctSttsHs" parameterType="com.its.vds.entity.voVdsDtctStts">
-    <![CDATA[
-          INSERT INTO TB_VDS_DTCT_STTS_HS (   
-		          CRTN_DT,                
-		          VDS_DTCT_NMBR,          
-		          DTCT_STTS 
-		         )           
-          VALUES (
-				  #{stts.UPDT_DT},
-				  #{stts.VDS_DTCT_NMBR},
-				  #{stts.DTCT_STTS}
-                 )
-    ]]>
-    </insert>
+    <!-- 용인시는 검지기상태정보 생성하지 않음  -->
+<!--    <insert id="insertVdsDtctSttsHs" parameterType="com.its.vds.entity.voVdsDtctStts">-->
+<!--    <![CDATA[-->
+<!--          INSERT INTO TB_VDS_DTCT_STTS_HS (   -->
+<!--		          CRTN_DT,                -->
+<!--		          VDS_DTCT_NMBR,          -->
+<!--		          DTCT_STTS -->
+<!--		         )           -->
+<!--          VALUES (-->
+<!--				  #{stts.UPDT_DT},-->
+<!--				  #{stts.VDS_DTCT_NMBR},-->
+<!--				  #{stts.DTCT_STTS}-->
+<!--                 )-->
+<!--    ]]>-->
+<!--    </insert>-->
 
     <insert id="insertVdsDtctClct" parameterType="com.its.vds.entity.voVdsDtctClct">
     <![CDATA[
-		INSERT INTO TB_VDS_DTCT_CLCT (  
-		            CLCT_DT,            
-		            VDS_DTCT_NMBR,      
-		            TRAF_CLCT_CYCL,     
-		            TFVL,               
-		            SPED,               
-		            AVRG_OCPY_RATE,     
-		            AVRG_LNGT,          
-		            HDWY,               
-		            SPCE_OCPY_RATE,     
-		            SPCE_AVRG_SPED      
-		   		  ) 
-		   VALUES (                   
-		           #{clct.CLCT_DT},
-		           #{clct.VDS_DTCT_NMBR},
-		           #{clct.TRAF_CLCT_CYCL},
-		           #{clct.TFVL},
-		           #{clct.SPED},
-		           #{clct.AVRG_OCPY_RATE},
-		           #{clct.AVRG_LNGT},
-		           #{clct.HDWY},
-		           #{clct.SPCE_OCPY_RATE},
-		           #{clct.SPCE_AVRG_SPED}
-		      )                         
+		INSERT INTO TB_VDS_DTCT_RAW_CLCT (
+            DTCT_NMBR,
+            OCRR_DT,
+            SYST_KIND_DVSN,
+            TFVL,
+            SPED,
+            AVRG_OCPY_RATE,
+            AVRG_LNGT,
+            HDWY
+          )
+		   VALUES (
+           #{clct.VDS_DTCT_NMBR},
+           #{clct.CLCT_DT},
+           #{clct.SYST_KIND_DVSN},
+           #{clct.TFVL},
+           #{clct.SPED},
+           #{clct.AVRG_OCPY_RATE},
+           #{clct.AVRG_LNGT},
+           #{clct.HDWY}
+      )
     ]]>
     </insert>
 
     <update id="updateVdsDtctClctPnst" parameterType="com.its.vds.entity.voVdsDtctClct">
     <![CDATA[
-		MERGE INTO TB_VDS_DTCT_CLCT_PNST L                 
-		USING (SELECT #{clct.VDS_DTCT_NMBR}  AS VDS_DTCT_NMBR,               
-		              #{clct.CLCT_DT} 	     AS CLCT_DT,                     
-		              #{clct.TRAF_CLCT_CYCL} AS TRAF_CLCT_CYCL,              
+		MERGE INTO TB_VDS_DTCT_RAW_PNST L
+		USING (SELECT #{clct.VDS_DTCT_NMBR}  AS DTCT_NMBR,
+		              #{clct.CLCT_DT} 	     AS OCRR_DT,
+		              #{clct.SYST_KIND_DVSN} AS SYST_KIND_DVSN,
 		              #{clct.TFVL}           AS TFVL,                        
 		              #{clct.SPED}           AS SPED,                        
 		              #{clct.AVRG_OCPY_RATE} AS AVRG_OCPY_RATE,              
@@ -113,71 +111,65 @@
 		              #{clct.SPCE_OCPY_RATE} AS SPCE_OCPY_RATE,              
 		              #{clct.SPCE_AVRG_SPED} AS SPCE_AVRG_SPED               
 		         FROM DUAL) M                              
-		        ON (L.VDS_DTCT_NMBR = M.VDS_DTCT_NMBR)     
+		        ON (L.DTCT_NMBR = M.DTCT_NMBR)
 		WHEN MATCHED THEN                                  
-		   UPDATE SET L.CLCT_DT        = M.CLCT_DT,        
-		              L.TRAF_CLCT_CYCL = M.TRAF_CLCT_CYCL, 
+		   UPDATE SET L.OCRR_DT        = M.OCRR_DT,
 		              L.TFVL           = M.TFVL,           
 		              L.SPED           = M.SPED,           
 		              L.AVRG_OCPY_RATE = M.AVRG_OCPY_RATE, 
 		              L.AVRG_LNGT      = M.AVRG_LNGT,      
-		              L.HDWY           = M.HDWY,           
-		              L.SPCE_OCPY_RATE = M.SPCE_OCPY_RATE, 
-		              L.SPCE_AVRG_SPED = M.SPCE_AVRG_SPED  
+		              L.HDWY           = M.HDWY
 		WHEN NOT MATCHED THEN                              
 		   INSERT (
-		           VDS_DTCT_NMBR,                          
-		           CLCT_DT,                                
-		           TRAF_CLCT_CYCL,                         
+                   DTCT_NMBR,
+                   OCRR_DT,
+                   SYST_KIND_DVSN,
 		           TFVL,                                   
 		           SPED,                                   
 		           AVRG_OCPY_RATE,                         
 		           AVRG_LNGT,                              
-		           HDWY,                                   
-		           SPCE_OCPY_RATE,                         
-		           SPCE_AVRG_SPED 
+		           HDWY
 		          )                        
-		   VALUES (M.VDS_DTCT_NMBR,                        
-		           M.CLCT_DT,                              
-		           M.TRAF_CLCT_CYCL,                       
+		   VALUES (M.DTCT_NMBR,
+		           M.OCRR_DT,
+		           M.SYST_KIND_DVSN,
 		           M.TFVL,                                 
 		           M.SPED,                                 
 		           M.AVRG_OCPY_RATE,                       
 		           M.AVRG_LNGT,                            
-		           M.HDWY,                                 
-		           M.SPCE_OCPY_RATE,                       
-		           M.SPCE_AVRG_SPED 
+		           M.HDWY
 		          )                      
     ]]>
     </update>
 
-    <insert id="insertVdsDtctVehClct" parameterType="com.its.vds.entity.voVdsDtctVehClct">
-    <![CDATA[
-		INSERT INTO TB_VDS_DTCT_VEH_CLCT (  
-		            CLCT_DT,                
-		            VDS_DTCT_NMBR,          
-		            CLCT_SEQ,               
-		            DETECT_LANE,            
-		            VEH_CLCT_DT,            
-		            SYNC_PASS_TIME,         
-		            SPED,                   
-		            OCPY_TIME,              
-		            VEH_TYPE,               
-		            HDWY_VEH_TIME           
-		   		  ) 
-		   VALUES (                       
-		           #{clct.CLCT_DT},                    
-		           #{clct.VDS_DTCT_NMBR},                    
-		           #{clct.CLCT_SEQ},                    
-		           #{clct.DETECT_LANE},                    
-		           #{clct.VEH_CLCT_DT},                    
-		           #{clct.SYNC_PASS_TIME},                    
-		           #{clct.SPED},                    
-		           #{clct.OCPY_TIME},                    
-		           #{clct.VEH_TYPE},                    
-		           #{clct.HDWY_VEH_TIME} 
-		          )                   
-    ]]>
-    </insert>
+    <!-- 용인시는 차량통과정보 생성하지 않음  -->
+<!--    <insert id="insertVdsDtctVehClct" parameterType="com.its.vds.entity.voVdsDtctVehClct">-->
+<!--    <![CDATA[-->
+<!--		INSERT INTO TB_VDS_DTCT_VEH_CLCT (  -->
+<!--		            CLCT_DT,                -->
+<!--		            VDS_DTCT_NMBR,          -->
+<!--		            CLCT_SEQ,               -->
+<!--		            DETECT_LANE,            -->
+<!--		            VEH_CLCT_DT,            -->
+<!--		            SYNC_PASS_TIME,         -->
+<!--		            SPED,                   -->
+<!--		            OCPY_TIME,              -->
+<!--		            VEH_TYPE,               -->
+<!--		            HDWY_VEH_TIME           -->
+<!--		   		  ) -->
+<!--		   VALUES (                       -->
+<!--		           #{clct.CLCT_DT},                    -->
+<!--		           #{clct.VDS_DTCT_NMBR},                    -->
+<!--		           #{clct.CLCT_SEQ},                    -->
+<!--		           #{clct.DETECT_LANE},                    -->
+<!--		           #{clct.VEH_CLCT_DT},                    -->
+<!--		           #{clct.SYNC_PASS_TIME},                    -->
+<!--		           #{clct.SPED},                    -->
+<!--		           #{clct.OCPY_TIME},                    -->
+<!--		           #{clct.VEH_TYPE},                    -->
+<!--		           #{clct.HDWY_VEH_TIME} -->
+<!--		          )                   -->
+<!--    ]]>-->
+<!--    </insert>-->
 
 </mapper>

+ 78 - 88
src/main/resources/mybatis/mapper/VdsStatMapper.xml

@@ -24,7 +24,7 @@
 		        ROUND(AVG(HDWY), 0)           AS HDWY,             
 		        AVG(SPCE_OCPY_RATE)           AS SPCE_OCPY_RATE,   
 		        ROUND(AVG(SPCE_AVRG_SPED), 0) AS SPCE_AVRG_SPED    
-		  FROM TB_VDS_DTCT_CLCT                                    
+		  FROM TB_VDS_DTCT_CLCT
 		 WHERE CLCT_DT BETWEEN #{prcs.FROM_DT} AND #{prcs.TO_DT}                      
 		 GROUP BY VDS_DTCT_NMBR                                    
     ]]>
@@ -32,82 +32,76 @@
 
     <insert id="CRT_TB_VDS_DTCT_15M_STAT" parameterType="com.its.vds.vo.voStatisticsTime">
     <![CDATA[
-		INSERT INTO TB_VDS_DTCT_15M_STAT (STAT_DT,                     
-		                                  VDS_DTCT_NMBR,               
+		INSERT INTO TB_VDS_DTCT_15M_STAT (STAT_DT,
+                                          DTCT_NMBR,
+                                          SYST_KIND_DVSN,
 		                                  TFVL,                        
 		                                  AVRG_SPED,                   
 		                                  AVRG_OCPY_RATE,              
 		                                  AVRG_LNGT,                   
-		                                  AVRG_HDWY,                   
-		                                  AVRG_SPCE_OCPY_RATE,         
-		                                  AVRG_SPCE_AVRG_SPED          
+		                                  AVRG_HDWY
 		                                 )                             
-		SELECT  #{prcs.STAT_DT}               AS STAT_DT,              
-		        VDS_DTCT_NMBR                 AS VDS_DTCT_NMBR,        
+		SELECT  #{prcs.STAT_DT}               AS STAT_DT,
+                DTCT_NMBR                     AS DTCT_NMBR,
+                MIN(SYST_KIND_DVSN)           AS SYST_KIND_DVSN,
 		        SUM(TFVL)                     AS TFVL,                 
 		        ROUND(AVG(SPED), 0)           AS AVRG_SPED,            
 		        AVG(AVRG_OCPY_RATE)           AS AVRG_OCPY_RATE,       
 		        AVG(AVRG_LNGT)                AS AVRG_LNGT,            
-		        ROUND(AVG(HDWY), 0)           AS AVRG_HDWY,            
-		        AVG(SPCE_OCPY_RATE)           AS AVRG_SPCE_OCPY_RATE,  
-		        ROUND(AVG(SPCE_AVRG_SPED), 0) AS AVRG_SPCE_AVRG_SPED   
-		  FROM TB_VDS_DTCT_HS                                          
-		 WHERE PRCN_DT BETWEEN #{prcs.FROM_DT} AND #{prcs.TO_DT}                           
-		 GROUP BY VDS_DTCT_NMBR                                        
+		        ROUND(AVG(HDWY), 0)           AS AVRG_HDWY
+		  FROM TB_VDS_DTCT_RAW_CLCT
+		 WHERE OCRR_DT BETWEEN #{prcs.FROM_DT} AND #{prcs.TO_DT}
+		 GROUP BY DTCT_NMBR
     ]]>
     </insert>
 
     <insert id="CRT_TB_VDS_DTCT_HH_STAT" parameterType="com.its.vds.vo.voStatisticsTime">
     <![CDATA[
-		INSERT INTO TB_VDS_DTCT_HH_STAT (STAT_DT,                           
-		                                 VDS_DTCT_NMBR,                     
+		INSERT INTO TB_VDS_DTCT_HH_STAT (STAT_DT,
+                                         DTCT_NMBR,
+                                         SYST_KIND_DVSN,
 		                                 TFVL,                              
 		                                 AVRG_SPED,                         
 		                                 AVRG_OCPY_RATE,                    
 		                                 AVRG_LNGT,                         
-		                                 AVRG_HDWY,                         
-		                                 AVRG_SPCE_OCPY_RATE,               
-		                                 AVRG_SPCE_AVRG_SPED                
+		                                 AVRG_HDWY
 		                                )                                   
-		SELECT  #{prcs.STAT_DT}                    AS STAT_DT,              
-		        VDS_DTCT_NMBR                      AS VDS_DTCT_NMBR,        
+		SELECT  #{prcs.STAT_DT}                    AS STAT_DT,
+                DTCT_NMBR                          AS DTCT_NMBR,
+                MIN(SYST_KIND_DVSN)                AS SYST_KIND_DVSN,
 		        SUM(TFVL)                          AS TFVL,                 
 		        ROUND(AVG(AVRG_SPED), 0)           AS AVRG_SPED,            
 		        AVG(AVRG_OCPY_RATE)                AS AVRG_OCPY_RATE,       
 		        AVG(AVRG_LNGT)                     AS AVRG_LNGT,            
-		        ROUND(AVG(AVRG_HDWY), 0)           AS AVRG_HDWY,            
-		        AVG(AVRG_SPCE_OCPY_RATE)           AS AVRG_SPCE_OCPY_RATE,  
-		        ROUND(AVG(AVRG_SPCE_AVRG_SPED), 0) AS AVRG_SPCE_AVRG_SPED   
+		        ROUND(AVG(AVRG_HDWY), 0)           AS AVRG_HDWY
 		  FROM TB_VDS_DTCT_15M_STAT                                         
 		 WHERE STAT_DT BETWEEN #{prcs.FROM_DT} AND #{prcs.TO_DT}                              
-		 GROUP BY VDS_DTCT_NMBR                                             
+		 GROUP BY DTCT_NMBR
     ]]>
     </insert>
 
     <insert id="CRT_TB_VDS_DTCT_DD_STAT" parameterType="com.its.vds.vo.voStatisticsTime">
     <![CDATA[
-		INSERT INTO TB_VDS_DTCT_DD_STAT (STAT_DT,                           
-		                                 VDS_DTCT_NMBR,                     
+		INSERT INTO TB_VDS_DTCT_DD_STAT (STAT_DT,
+                                         DTCT_NMBR,
+                                         SYST_KIND_DVSN,
 		                                 TFVL,                              
 		                                 AVRG_SPED,                         
 		                                 AVRG_OCPY_RATE,                    
 		                                 AVRG_LNGT,                         
-		                                 AVRG_HDWY,                         
-		                                 AVRG_SPCE_OCPY_RATE,               
-		                                 AVRG_SPCE_AVRG_SPED                
+		                                 AVRG_HDWY
 		                                )                                   
-		SELECT  #{prcs.STAT_DT}                    AS STAT_DT,              
-		        VDS_DTCT_NMBR                      AS VDS_DTCT_NMBR,        
+		SELECT  #{prcs.STAT_DT}                    AS STAT_DT,
+                DTCT_NMBR                          AS DTCT_NMBR,
+                MIN(SYST_KIND_DVSN)                AS SYST_KIND_DVSN,
 		        SUM(TFVL)                          AS TFVL,                 
 		        ROUND(AVG(AVRG_SPED), 0)           AS AVRG_SPED,            
 		        AVG(AVRG_OCPY_RATE)                AS AVRG_OCPY_RATE,       
 		        AVG(AVRG_LNGT)                     AS AVRG_LNGT,            
-		        ROUND(AVG(AVRG_HDWY), 0)           AS AVRG_HDWY,            
-		        AVG(AVRG_SPCE_OCPY_RATE)           AS AVRG_SPCE_OCPY_RATE,  
-		        ROUND(AVG(AVRG_SPCE_AVRG_SPED), 0) AS AVRG_SPCE_AVRG_SPED   
+		        ROUND(AVG(AVRG_HDWY), 0)           AS AVRG_HDWY
 		  FROM TB_VDS_DTCT_HH_STAT                                          
 		 WHERE STAT_DT BETWEEN #{prcs.FROM_DT} AND #{prcs.TO_DT}                               
-		 GROUP BY VDS_DTCT_NMBR                                             
+		 GROUP BY DTCT_NMBR
     ]]>
     </insert>
 
@@ -115,70 +109,66 @@
     <![CDATA[
 		MERGE INTO TB_VDS_DTCT_MN_STAT L                                    
 		USING (                                                             
-		SELECT  #{prcs.STAT_DT}                    AS STAT_DT,              
-		        VDS_DTCT_NMBR                      AS VDS_DTCT_NMBR,        
+		SELECT  #{prcs.STAT_DT}                    AS STAT_DT,
+                DTCT_NMBR                          AS DTCT_NMBR,
+                MIN(SYST_KIND_DVSN)                AS SYST_KIND_DVSN,
 		        SUM(TFVL)                          AS TFVL,                 
 		        ROUND(AVG(AVRG_SPED), 0)           AS AVRG_SPED,            
 		        AVG(AVRG_OCPY_RATE)                AS AVRG_OCPY_RATE,       
 		        AVG(AVRG_LNGT)                     AS AVRG_LNGT,            
-		        ROUND(AVG(AVRG_HDWY), 0)           AS AVRG_HDWY,            
-		        AVG(AVRG_SPCE_OCPY_RATE)           AS AVRG_SPCE_OCPY_RATE,  
-		        ROUND(AVG(AVRG_SPCE_AVRG_SPED), 0) AS AVRG_SPCE_AVRG_SPED   
+		        ROUND(AVG(AVRG_HDWY), 0)           AS AVRG_HDWY
 		  FROM TB_VDS_DTCT_DD_STAT                                          
 		 WHERE STAT_DT BETWEEN #{prcs.FROM_DT} AND #{prcs.TO_DT}                                
-		 GROUP BY VDS_DTCT_NMBR ) M                                         
-		ON (L.STAT_DT = M.STAT_DT AND L.VDS_DTCT_NMBR = M.VDS_DTCT_NMBR)    
-		WHEN MATCHED THEN UPDATE SET                                        
-		       L.TFVL                = M.TFVL,                              
+		 GROUP BY DTCT_NMBR ) M
+		ON (L.STAT_DT = M.STAT_DT AND L.DTCT_NMBR = M.DTCT_NMBR AND L.SYST_KIND_DVSN = M.SYST_KIND_DVSN)
+		WHEN MATCHED THEN UPDATE SET
+               L.TFVL                = M.TFVL,
 		       L.AVRG_SPED           = M.AVRG_SPED,                         
 		       L.AVRG_OCPY_RATE      = M.AVRG_OCPY_RATE,                    
 		       L.AVRG_LNGT           = M.AVRG_LNGT,                         
-		       L.AVRG_HDWY           = M.AVRG_HDWY,                         
-		       L.AVRG_SPCE_OCPY_RATE = M.AVRG_SPCE_OCPY_RATE,               
-		       L.AVRG_SPCE_AVRG_SPED = M.AVRG_SPCE_AVRG_SPED                
+		       L.AVRG_HDWY           = M.AVRG_HDWY
 		WHEN NOT MATCHED THEN                                               
-		INSERT(L.STAT_DT, L.VDS_DTCT_NMBR, L.TFVL, L.AVRG_SPED,             
-		       L.AVRG_OCPY_RATE, L.AVRG_LNGT, L.AVRG_HDWY,                  
-		       L.AVRG_SPCE_OCPY_RATE, L.AVRG_SPCE_AVRG_SPED )               
-		VALUES(M.STAT_DT, M.VDS_DTCT_NMBR, M.TFVL, M.AVRG_SPED,             
-		       M.AVRG_OCPY_RATE, M.AVRG_LNGT, M.AVRG_HDWY,                  
-		       M.AVRG_SPCE_OCPY_RATE, M.AVRG_SPCE_AVRG_SPED )               
+		INSERT(L.STAT_DT, L.DTCT_NMBR, L.SYST_KIND_DVSN, L.TFVL, L.AVRG_SPED,
+		       L.AVRG_OCPY_RATE, L.AVRG_LNGT, L.AVRG_HDWY )
+		VALUES(M.STAT_DT, M.DTCT_NMBR, M.SYST_KIND_DVSN, M.TFVL, M.AVRG_SPED,
+		       M.AVRG_OCPY_RATE, M.AVRG_LNGT, M.AVRG_HDWY )
     ]]>
     </update>
 
-    <update id="CRT_TB_VDS_DTCT_YY_STAT" parameterType="com.its.vds.vo.voStatisticsTime">
-    <![CDATA[
-		MERGE INTO TB_VDS_DTCT_YY_STAT L                                    
-		USING (                                                             
-		SELECT  #{prcs.STAT_DT}                    AS STAT_DT,              
-		        VDS_DTCT_NMBR                      AS VDS_DTCT_NMBR,        
-		        SUM(TFVL)                          AS TFVL,                 
-		        ROUND(AVG(AVRG_SPED), 0)           AS AVRG_SPED,            
-		        AVG(AVRG_OCPY_RATE)                AS AVRG_OCPY_RATE,       
-		        AVG(AVRG_LNGT)                     AS AVRG_LNGT,            
-		        ROUND(AVG(AVRG_HDWY), 0)           AS AVRG_HDWY,            
-		        AVG(AVRG_SPCE_OCPY_RATE)           AS AVRG_SPCE_OCPY_RATE,  
-		        ROUND(AVG(AVRG_SPCE_AVRG_SPED), 0) AS AVRG_SPCE_AVRG_SPED   
-		  FROM TB_VDS_DTCT_MN_STAT                                          
-		 WHERE STAT_DT BETWEEN #{prcs.FROM_DT} AND #{prcs.TO_DT}                                
-		 GROUP BY VDS_DTCT_NMBR ) M                                         
-		ON (L.STAT_DT = M.STAT_DT AND L.VDS_DTCT_NMBR = M.VDS_DTCT_NMBR)    
-		WHEN MATCHED THEN UPDATE SET                                        
-		       L.TFVL                = M.TFVL,                              
-		       L.AVRG_SPED           = M.AVRG_SPED,                         
-		       L.AVRG_OCPY_RATE      = M.AVRG_OCPY_RATE,                    
-		       L.AVRG_LNGT           = M.AVRG_LNGT,                         
-		       L.AVRG_HDWY           = M.AVRG_HDWY,                         
-		       L.AVRG_SPCE_OCPY_RATE = M.AVRG_SPCE_OCPY_RATE,               
-		       L.AVRG_SPCE_AVRG_SPED = M.AVRG_SPCE_AVRG_SPED                
-		WHEN NOT MATCHED THEN                                               
-		INSERT(L.STAT_DT, L.VDS_DTCT_NMBR, L.TFVL, L.AVRG_SPED,             
-		       L.AVRG_OCPY_RATE, L.AVRG_LNGT, L.AVRG_HDWY,                  
-		       L.AVRG_SPCE_OCPY_RATE, L.AVRG_SPCE_AVRG_SPED )               
-		VALUES(M.STAT_DT, M.VDS_DTCT_NMBR, M.TFVL, M.AVRG_SPED,             
-		       M.AVRG_OCPY_RATE, M.AVRG_LNGT, M.AVRG_HDWY,                  
-		       M.AVRG_SPCE_OCPY_RATE, M.AVRG_SPCE_AVRG_SPED )               
-    ]]>
-    </update>
+    <!-- 용인시는 년 통계정보 생성하지 않음  -->
+<!--    <update id="CRT_TB_VDS_DTCT_YY_STAT" parameterType="com.its.vds.vo.voStatisticsTime">-->
+<!--    <![CDATA[-->
+<!--		MERGE INTO TB_VDS_DTCT_YY_STAT L                                    -->
+<!--		USING (                                                             -->
+<!--		SELECT  #{prcs.STAT_DT}                    AS STAT_DT,              -->
+<!--		        VDS_DTCT_NMBR                      AS VDS_DTCT_NMBR,        -->
+<!--		        SUM(TFVL)                          AS TFVL,                 -->
+<!--		        ROUND(AVG(AVRG_SPED), 0)           AS AVRG_SPED,            -->
+<!--		        AVG(AVRG_OCPY_RATE)                AS AVRG_OCPY_RATE,       -->
+<!--		        AVG(AVRG_LNGT)                     AS AVRG_LNGT,            -->
+<!--		        ROUND(AVG(AVRG_HDWY), 0)           AS AVRG_HDWY,            -->
+<!--		        AVG(AVRG_SPCE_OCPY_RATE)           AS AVRG_SPCE_OCPY_RATE,  -->
+<!--		        ROUND(AVG(AVRG_SPCE_AVRG_SPED), 0) AS AVRG_SPCE_AVRG_SPED   -->
+<!--		  FROM TB_VDS_DTCT_MN_STAT                                          -->
+<!--		 WHERE STAT_DT BETWEEN #{prcs.FROM_DT} AND #{prcs.TO_DT}                                -->
+<!--		 GROUP BY VDS_DTCT_NMBR ) M                                         -->
+<!--		ON (L.STAT_DT = M.STAT_DT AND L.VDS_DTCT_NMBR = M.VDS_DTCT_NMBR)    -->
+<!--		WHEN MATCHED THEN UPDATE SET                                        -->
+<!--		       L.TFVL                = M.TFVL,                              -->
+<!--		       L.AVRG_SPED           = M.AVRG_SPED,                         -->
+<!--		       L.AVRG_OCPY_RATE      = M.AVRG_OCPY_RATE,                    -->
+<!--		       L.AVRG_LNGT           = M.AVRG_LNGT,                         -->
+<!--		       L.AVRG_HDWY           = M.AVRG_HDWY,                         -->
+<!--		       L.AVRG_SPCE_OCPY_RATE = M.AVRG_SPCE_OCPY_RATE,               -->
+<!--		       L.AVRG_SPCE_AVRG_SPED = M.AVRG_SPCE_AVRG_SPED                -->
+<!--		WHEN NOT MATCHED THEN                                               -->
+<!--		INSERT(L.STAT_DT, L.VDS_DTCT_NMBR, L.TFVL, L.AVRG_SPED,             -->
+<!--		       L.AVRG_OCPY_RATE, L.AVRG_LNGT, L.AVRG_HDWY,                  -->
+<!--		       L.AVRG_SPCE_OCPY_RATE, L.AVRG_SPCE_AVRG_SPED )               -->
+<!--		VALUES(M.STAT_DT, M.VDS_DTCT_NMBR, M.TFVL, M.AVRG_SPED,             -->
+<!--		       M.AVRG_OCPY_RATE, M.AVRG_LNGT, M.AVRG_HDWY,                  -->
+<!--		       M.AVRG_SPCE_OCPY_RATE, M.AVRG_SPCE_AVRG_SPED )               -->
+<!--    ]]>-->
+<!--    </update>-->
 
 </mapper>