Procházet zdrojové kódy

center communication add

shjung před 3 roky
rodič
revize
8f3324f09e

+ 14 - 6
src/main/java/com/its/api/utils/ItsUtils.java

@@ -315,13 +315,21 @@ public final class ItsUtils
 
 	public static List<String> split(String value, String delim) {
 
-	List<String> list = new ArrayList<String>();
+		List<String> list = new ArrayList<String>();
 
-	StringTokenizer stringTokenizer = new StringTokenizer(value, delim);
-	while (stringTokenizer.hasMoreTokens()) {
-		list.add(stringTokenizer.nextToken().trim());
+		StringTokenizer stringTokenizer = new StringTokenizer(value, delim);
+		while (stringTokenizer.hasMoreTokens()) {
+			list.add(stringTokenizer.nextToken().trim());
+		}
+
+		return list;
 	}
 
-	return list;
-}
+	public static int swapENdian(int x) {
+		return swapEndian((short)x) << 16 | swapEndian((short)(x >> 16)) & 0xFFFF;
+	}
+
+	public static short swapEndian(short x) {
+		return (short)(x << 8 | x >> 8 & 0xFF);
+	}
 }

+ 27 - 10
src/main/java/com/its/api/xnetudp/CenterCommUdpServer.java

@@ -4,10 +4,7 @@ import com.its.api.config.CenterCommConfig;
 import com.its.api.xnetudp.codec.CenterCommServerDecoder;
 import com.its.api.xnetudp.handler.CenterCommServerPacketHandler;
 import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.EventLoopGroup;
+import io.netty.channel.*;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.nio.NioDatagramChannel;
 import lombok.RequiredArgsConstructor;
@@ -25,6 +22,7 @@ public class CenterCommUdpServer {
 
     private EventLoopGroup nioEventLoopGroup;
     private Bootstrap bootstrap;
+    private boolean isThreadRunning = false;
 
     public void run() {
         log.info("UdpServerCenterComm.init: Start.");
@@ -34,8 +32,11 @@ public class CenterCommUdpServer {
             this.bootstrap = new Bootstrap();
             this.bootstrap.channel(NioDatagramChannel.class);
             this.bootstrap.group(this.nioEventLoopGroup);
-            this.bootstrap.option(ChannelOption.SO_BROADCAST, Boolean.valueOf(true));
-            this.bootstrap.option(ChannelOption.SO_REUSEADDR, Boolean.valueOf(true));
+            this.bootstrap.option(ChannelOption.SO_BROADCAST, false);
+            this.bootstrap.option(ChannelOption.SO_REUSEADDR, true);
+            this.bootstrap.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(8192));
+            this.bootstrap.option(ChannelOption.SO_RCVBUF, 8192);
+            this.bootstrap.option(ChannelOption.SO_SNDBUF, 8192);
             this.bootstrap.handler(new ChannelInitializer<Channel>() {
                 @Override
                 protected void initChannel(Channel channel) throws Exception
@@ -57,17 +58,33 @@ public class CenterCommUdpServer {
 
         try {
             if (this.serverConfig.getBindingAddr().equals("0.0.0.0")) {
-                this.bootstrap.bind(this.serverConfig.getBindingPort());
+                if (isThreadRunning) {
+                    this.bootstrap.bind(this.serverConfig.getBindingPort()).sync().channel().closeFuture().await();
+                }
+                else {
+                    this.bootstrap.bind(this.serverConfig.getBindingPort());
+                }
             }
             else {
-                this.bootstrap.bind(this.serverConfig.getBindingAddr(), serverConfig.getBindingPort());
+                if (isThreadRunning) {
+                    this.bootstrap.bind(this.serverConfig.getBindingAddr(), serverConfig.getBindingPort()).sync().channel().closeFuture().await();
+                }
+                else {
+                    this.bootstrap.bind(this.serverConfig.getBindingAddr(), serverConfig.getBindingPort());
+                }
             }
         }
         catch (Exception e) {
-            this.log.error("UdpServerCenterComm.init: Bind Exception: {}", e.toString());
-            this.nioEventLoopGroup.shutdownGracefully();
+            e.printStackTrace();
+            log.error("UdpServerCenterComm.init: Bind Exception: {}", e.toString());
+            if (!isThreadRunning) {
+                this.nioEventLoopGroup.shutdownGracefully();
+            }
         }
         finally {
+            if (isThreadRunning) {
+                this.nioEventLoopGroup.shutdownGracefully();
+            }
         }
         log.info("UdpServerCenterComm.init: ..End. {}", toString());
     }

+ 16 - 8
src/main/java/com/its/api/xnetudp/protocol/CENTER_COMM_DEFINE.java

@@ -57,18 +57,23 @@ public class CENTER_COMM_DEFINE {
 	/*******************************************************************************
 	 * VMS Protocol OP Code
 	 *******************************************************************************/
-	public static final int INT_OP_VMS_STATE_REQ            = 0x21;        /* VMS 통신 서버, VMS 시설물 상태정보 요청 */
-	public static final int INT_OP_VMS_STATE_RES            = 0x22;        /* VMS 통신 서버, VMS 시설물 상태정보 전송 */
-	public static final int INT_OP_VMS_POWER_CTL            = 0x23;        /* VMS 통신 서버, VMS 전광판 On/Off 제어 */
-	public static final int INT_OP_VMS_LUMINANCE_CTL        = 0x24;        /* VMS 통신 서버, VMS 휘도 제어 */
+	public static final int INT_OP_VMS_STATE_REQ            = 0x01;        /* VMS 통신 서버, VMS 시설물 상태정보 요청 */
+	public static final int INT_OP_VMS_STATE_RES            = 0x02;        /* VMS 통신 서버, VMS 시설물 상태정보 전송 */
+	public static final int INT_OP_VMS_POWER_CTL            = 0x03;        /* VMS 통신 서버, VMS 전광판 On/Off 제어 */
+	public static final int INT_OP_VMS_LUMINANCE_CTL        = 0x04;        /* VMS 통신 서버, VMS 휘도 제어 */
+	//public static final int INT_OP_VMS_STATE_REQ            = 0x21;        /* VMS 통신 서버, VMS 시설물 상태정보 요청 */
+	//public static final int INT_OP_VMS_STATE_RES            = 0x22;        /* VMS 통신 서버, VMS 시설물 상태정보 전송 */
+	//public static final int INT_OP_VMS_POWER_CTL            = 0x23;        /* VMS 통신 서버, VMS 전광판 On/Off 제어 */
+	//public static final int INT_OP_VMS_LUMINANCE_CTL        = 0x24;        /* VMS 통신 서버, VMS 휘도 제어 */
 
 	public static final int INT_OP_VMS_PARA_SET             = 0x25;        /* VMS 통신 서버, VMS 환경설정정보 전송 */
 	public static final int INT_OP_VMS_PARA_SET2            = 0x26;        /* VMS 통신 서버, VMS 환경설정정보 전송(For Pasig) */
 	public static final int INT_OP_VMS_RESET                = 0x27;        /* VMS 통신 서버, VMS 제어기 리셋 전송 */
 	public static final int INT_OP_VMS_MODE                 = 0x28;        /* VMS 통신 서버, VMS 운영모드 변경 */
-	public static final int INT_OP_VMS_FORM_SAVE            = 0x29;        /* VMS 통신 서버, 실시간 VMS 제공정보 저장 */
+	public static final int INT_OP_VMS_FORM_SAVE            = 0x0B;        /* VMS 통신 서버, 실시간 VMS 제공정보 저장 */
+	public static final int INT_OP_VMS_FORM_DOWNLOAD        = 0x0C;        /* VMS 통신 서버, 실시간 VMS 제공정보 다운로드 결과 저장 */
 	//public static final int INT_OP_VMS_FORM_DOWNLOAD        = 0x2A;        /* VMS 통신 서버, 실시간 VMS 제공정보 저장 */
-	public static final int INT_OP_VMS_FORM_DOWNLOAD        = 0x0C;        /* VMS 통신 서버, 실시간 VMS 제공정보 저장 */
+	//public static final int INT_OP_VMS_FORM_SAVE            = 0x29;        /* VMS 통신 서버, 실시간 VMS 제공정보 저장 */
 	public static final int INT_OP_VMS_IMAGE_SYMBOL         = 0x2B;        /* VMS image symbol update */
 	public static final int INT_OP_VMS_IMAGE_TRAFFIC        = 0x2C;        /* VMS image traffic update */
 	public static final int INT_OP_VMS_FORM_UPDATE          = 0x2D;        /* VMS form update */
@@ -137,8 +142,11 @@ public class CENTER_COMM_DEFINE {
 	public static final int INT_VMS_MAX_ID              = 15;       /* VMS 제어기 ID */
 	public static final int INT_VMS_MAX_MODULE          = 100;      /* 최대 VMS 모듈 */
 	public static final int INT_VMS_MAX_POWER           = 10;       /* 최대 VMS 전원 */
-	public static final int INT_VMS_MAX_MODULE_BIT      = 100;      /* 최대 VMS 모듈 비트*/
-	public static final int INT_VMS_MAX_POWER_BIT       = 10;       /* 최대 VMS 전원 비트 */
+	public static final int INT_VMS_MAX_MODULE_BIT      = 25;       /* 최대 VMS 모듈 비트*/
+	public static final int INT_VMS_MAX_POWER_BIT       = 2;        /* 최대 VMS 전원 비트 */
+	//public static final int INT_VMS_MAX_MODULE_BIT      = 100;      /* 최대 VMS 모듈 비트*/
+	//public static final int INT_VMS_MAX_POWER_BIT       = 10;       /* 최대 VMS 전원 비트 */
+	public static final int INT_VMS_STATUE_DUMMY        = 4;           /* dummy */
 
 	public static final int INT_VMS_MAX_DATETIME        = 14;       /* YYYYMMDDHHMMSS */
 	public static final int INT_VMS_MAX_OPER_ID         = 20;

+ 9 - 6
src/main/java/com/its/api/xnetudp/protocol/CENTER_COMM_MESSAGE.java

@@ -1,5 +1,6 @@
 package com.its.api.xnetudp.protocol;
 
+import com.its.api.utils.SysUtils;
 import lombok.extern.slf4j.Slf4j;
 
 import java.net.InetSocketAddress;
@@ -9,7 +10,7 @@ import java.nio.ByteOrder;
 @Slf4j
 public class CENTER_COMM_MESSAGE {
 
-	public static int CENTER_HEADER_SIZE = 8; 
+	public static int CENTER_HEADER_SIZE = 10;
 	
 	private InetSocketAddress sender;
 	
@@ -50,14 +51,16 @@ public class CENTER_COMM_MESSAGE {
 		this.opCode       = byteBuffer.get();
 		int  length       = byteBuffer.getInt();
 		this.length = byteBuffer.array().length - 10;
-		if (length != this.length) {
-			log.error("######################################################################Length Error: {}, {}", length, this.length);
-			log.error("######################################################################Length Error: {}, {}", length, this.length);
-			log.error("######################################################################Length Error: {}, {}", length, this.length);
-		}
 		if (this.length > 0) {
 			this.body = new byte[this.length];
 			byteBuffer.get(this.body);
+
+			if (length != this.length) {
+				log.error("######################################################################");
+				log.error("######################################################################");
+				log.error("######################################################################, Length Error: {}, {}, {}", length, this.length, buffer.length);
+				log.error("VMS PACKET: {}", SysUtils.byteArrayToHex(buffer));
+			}
 		}
 	}
 

+ 85 - 21
src/main/java/com/its/api/xnetudp/thread/CenterCommServerReceiver.java

@@ -22,7 +22,7 @@ public class CenterCommServerReceiver {
 
         if (CENTER_COMM_DEFINE.INT_ID_TRAFFIC_SERVER == data.getSendId()) {
             if (CENTER_COMM_DEFINE.INT_OP_TRAFFIC_CHANGE == data.getOpCode()) {
-                log.error("RECV Traffic server job completed.");
+                log.error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ RECV Traffic server job completed.");
             }
             return;
         }
@@ -30,38 +30,102 @@ public class CenterCommServerReceiver {
         // VMS 통신 서버는 Sender, Receiver 위치가 바뀌었음. ==> 서버 수정했음.
         //if (CENTER_COMM_DEFINE.INT_ID_VMS_OPER == data.getSendId() && CENTER_COMM_DEFINE.INT_ID_VMS_SERVER == data.getRecvId()) {
         if (CENTER_COMM_DEFINE.INT_ID_VMS_SERVER == data.getSendId()) {
-            log.error("RECV VMS Server Message: {}, Length: {} Bytes.", data.getOpCode(), data.getLength());
+            log.error("RECV VMS Server Message[0xFF]: Length: {} Bytes.", data.getLength());
             //log.error("VMS PACKET: {}", SysUtils.byteArrayToHex(data.getBody()));
             if (data.getLength() > 0) {
                 ByteBuffer byteBuffer = ByteBuffer.wrap(data.getBody());
-                byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+                byteBuffer.order(ByteOrder.BIG_ENDIAN);
 
+                byte[] vmsId;
+                byte count;
                 byte opCode = byteBuffer.get();
                 byte msgSeq = byteBuffer.get();
                 log.error("OP CODE: {}, MsgSeq: {}", opCode, msgSeq);
-                if (CENTER_COMM_DEFINE.INT_OP_VMS_FORM_DOWNLOAD == opCode) {
-                    byte count = byteBuffer.get();
-                    log.error("download count: {} EA", count);
-                    for (int ii = 0; ii < count; ii++) {
-                        byte[] vmsId = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_ID];
-                        byte[] downloadDt  = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_DATETIME];
-                        byteBuffer.get(vmsId);
-                        byteBuffer.get(downloadDt);
-                        byte result = byteBuffer.get();
-
-                        for (int jj = 0; jj < vmsId.length; jj++) {
-                            if (vmsId[jj] < '0' || vmsId[jj] > '9') {
-                                vmsId[jj] = ' ';
+                switch(opCode) {
+                    case CENTER_COMM_DEFINE.INT_OP_VMS_FORM_DOWNLOAD:
+                        count = byteBuffer.get();
+                        log.error("INT_OP_VMS_FORM_DOWNLOAD: Count: {} EA", count);
+                        for (int ii = 0; ii < count; ii++) {
+                            vmsId = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_ID];
+                            byte[] downloadDt  = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_DATETIME];
+                            byteBuffer.get(vmsId);
+                            byteBuffer.get(downloadDt);
+                            byte result = byteBuffer.get();
+
+                            for (int jj = 0; jj < vmsId.length; jj++) {
+                                if (vmsId[jj] < '0' || vmsId[jj] > '9') {
+                                    vmsId[jj] = ' ';
+                                }
                             }
+                            //log.error("{}, {}, {}, {}", ii+1, new String(vmsId).trim(), new String(downloadDt), result);
                         }
-                        log.error("{}, {}, {}, {}", ii+1, new String(vmsId).trim(), new String(downloadDt), result);
+                        break;
+                    case CENTER_COMM_DEFINE.INT_OP_VMS_FORM_SAVE:
+                        byte[] saveDt  = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_DATETIME];
+                        byteBuffer.get(saveDt);
+                        log.error("INT_OP_VMS_FORM_SAVE: SaveTime: {}", new String(saveDt));
+                        break;
+                    case CENTER_COMM_DEFINE.INT_OP_VMS_STATE_RES:
+                        short total = byteBuffer.getShort();
+                        short error = byteBuffer.getShort();
+                        short normal = byteBuffer.getShort();
+                        short module = byteBuffer.getShort();
+                        count = byteBuffer.get();
+                        log.error("INT_OP_VMS_STATE_RES: total({}), error({}), normal({}), module({}), count: {} EA.", total, error, normal, module, count);
+                        for (int ii = 0; ii < count; ii++) {
+                            vmsId = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_ID];
+                            byteBuffer.get(vmsId);
+                            byte  OprMode = byteBuffer.get();                                      /* VMS운영모드, 0:auto, 1:Fix */
+                            byte  Comm = byteBuffer.get();                                         /* 유선통신상태, 0:정상 1:장애 */
+                            byte  Wcomm = byteBuffer.get();                                        /* 무선통신상태, 0:정상 1:장애 */
+
+                            byte  DoorStatus = byteBuffer.get();                                   /* 도어상태정보코드,     0:열림 1:닫힘 2:알수없음 */
+                            byte  ModulePowerStatus = byteBuffer.get();                            /* 모듈전원상태정보코드, 0:켜짐 1:꺼짐 2:알수없음 */
+                            short BodyTemp = byteBuffer.getShort();                                     /* 함체온도값(℃), 범위(-128~127) */
+                            byte  LuminanceStatus = byteBuffer.get();                              /* 화면의 밝기값 (최대 휘도값을 100으로 했을 때의 백분율 값), 범위(0~100) */
+                            byte  FanStatus = byteBuffer.get();                                    /* Fan 동작상태정보코드,    0:켜짐, 1:꺼짐 2:알수없음 */
+                            byte  HeaterStatus = byteBuffer.get();                                 /* Heater 동작상태정보코드, 0:켜짐, 1:꺼짐 2:알수없음 */
+
+                            byte  ExternalLightStatus = byteBuffer.get();                          /* 선택 외부조명 동작상태정보코드 0:켜짐, 1:꺼짐, 2:자동(공단은 미사용) */
+                            byte  AlarmLightStatus = byteBuffer.get();                             /* 선택 경광등 동작상태정보코드   0:켜짐, 1:꺼짐 */
+                            byte  SpeakerStatus = byteBuffer.get();                                /* 선택 스피커 동작상태정보코드   0:켜짐, 1:꺼짐 */
+                            byte[] ControllerCurrentTime  = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_DATETIME];
+                            byteBuffer.get(ControllerCurrentTime);
+                            byte  Voltage = byteBuffer.get();                                      /* 전압, 범위(0~255), 사용안함 */
 
-                    }
+                            byte  ModuleState = byteBuffer.get();                                  /* 모듈 상태, 0:정상 1:장애 2:알수없음 */
+                            byte  ModuleHorizontal = byteBuffer.get();                             /* 가로 모듈수 */
+                            byte  ModuleVertical = byteBuffer.get();                               /* 세로 모듈수 */
+                            byte[]  ModuleStatus = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_MODULE_BIT];         /* 모듈 개별 상태, 0:정상 1:장애 2:알수없음 */
+                            byteBuffer.get(ModuleStatus);
+                            byte  PowerCount = byteBuffer.get();                                   /* 전원 갯수 */
+                            byte[]  PowerStatus = new byte[CENTER_COMM_DEFINE.INT_VMS_MAX_POWER_BIT];           /* 전원 개별 상태, 0:켜짐 1:꺼짐 2:알수없음 */
+                            byteBuffer.get(PowerStatus);
+                            byte[]  Dummy = new byte[CENTER_COMM_DEFINE.INT_VMS_STATUE_DUMMY];                  /* protocol dummy bytes */
+                            byteBuffer.get(Dummy);
+                            short ScheduledMessageOperatingTime = byteBuffer.getShort();                /* 필수 계획된 메시지의 동작시간(초) */
+                            short ModuleOperatingTemperature = byteBuffer.getShort();                   /* 필수 모듈 전원이 꺼지는 온도값(℃) */
+                            short FanOperatingTemperature = byteBuffer.getShort();                      /* 필수 Fan 동작 기준 온도값(℃) */
+                            short HeaterOperatingTemperature = byteBuffer.getShort();                   /* 필수 Heater 동작 기준 온도값(℃) */
+                            short ExternalLightOperatingLuminance = byteBuffer.getShort();              /* 선택 외부전등 동작 기준 휘도값 */
+                            short ModuleBasicFailureRate = byteBuffer.getShort();                       /* 선택 모듈 장애율 (한 개의 모듈을 장애로 처리하기 위한 픽셀의 백분율값) */
+                            short MaximumRetry = byteBuffer.getShort();                                 /* 선택 최대 재시도 횟수(회) */
+                            short ResponseTimeOut = byteBuffer.getShort();                              /* 선택 최대응답대기시간 (초) */
+                            short BlinkingCycleTime = byteBuffer.getShort();                            /* 선택 점멸시간 주기 ( 1/10초단위) */
+
+                            for (int jj = 0; jj < vmsId.length; jj++) {
+                                if (vmsId[jj] < '0' || vmsId[jj] > '9') {
+                                    vmsId[jj] = ' ';
+                                }
+                            }
+                            log.error("{}, VmsId: {}, ModuleHor: {}, ModuleVer: {}", ii+1, new String(vmsId).trim(), ModuleHorizontal, ModuleVertical);
+                        }
+                        break;
+                    default:
+                        log.error("Other opCode: {}", opCode);
+                        break;
                 }
             }
-            //switch(data.getOpCode()) {
-//
-//            }
         }
 
         String reqIpAddr = data.getSenderIp();

+ 2 - 0
src/main/resources/application-dev.yml

@@ -7,7 +7,9 @@ spring:
       password: yiits
       minimumIdle: 5
       maximumIdle: 10
+      maximumPoolSize: 20
       idleTimeout: 30000
+      connectTimeout: 10000
   jpa:
     database-platform: org.hibernate.dialect.Oracle10gDialect
     properties: