win 0211
commit
b2856d00ee
|
@ -0,0 +1,33 @@
|
||||||
|
HELP.md
|
||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
Binary file not shown.
|
@ -0,0 +1,18 @@
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you under the Apache License, Version 2.0 (the
|
||||||
|
# "License"); you may not use this file except in compliance
|
||||||
|
# with the License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing,
|
||||||
|
# software distributed under the License is distributed on an
|
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
# KIND, either express or implied. See the License for the
|
||||||
|
# specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.7/apache-maven-3.8.7-bin.zip
|
||||||
|
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="euc-kr"?>
|
||||||
|
<Root Updated="2015-02-05 12:39:27">
|
||||||
|
|
||||||
|
<!-- CAT-11 -->
|
||||||
|
<UdpSocket>
|
||||||
|
<Connection ID="0" Tag="1" USE="false" Name="udp_recv_test_2284" PIP="127.0.0.1" SIP="127.0.0.1" PORT="55304"/>
|
||||||
|
<Option LineMode="TURE" InOut="recv" McastGrp="+239.192.201.7"/>
|
||||||
|
<Reconnect ReconnUSE="TRUE" Interval="600"/>
|
||||||
|
</UdpSocket>
|
||||||
|
|
||||||
|
<!-- CAT-10 -->
|
||||||
|
<UdpSocket>
|
||||||
|
<Connection ID="1" Tag="2" USE="true" Name="udp_rec239.11.12.5v_test_3384" PIP="127.0.0.1" SIP="127.0.0.1" PORT="52114"/>
|
||||||
|
<Option LineMode="TURE" InOut="recv" McastGrp="+239.11.12.5"/>
|
||||||
|
<Reconnect ReconnUSE="TRUE" Interval="600"/>
|
||||||
|
</UdpSocket>
|
||||||
|
|
||||||
|
|
||||||
|
</Root>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,188 @@
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@REM or more contributor license agreements. See the NOTICE file
|
||||||
|
@REM distributed with this work for additional information
|
||||||
|
@REM regarding copyright ownership. The ASF licenses this file
|
||||||
|
@REM to you under the Apache License, Version 2.0 (the
|
||||||
|
@REM "License"); you may not use this file except in compliance
|
||||||
|
@REM with the License. You may obtain a copy of the License at
|
||||||
|
@REM
|
||||||
|
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@REM
|
||||||
|
@REM Unless required by applicable law or agreed to in writing,
|
||||||
|
@REM software distributed under the License is distributed on an
|
||||||
|
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
@REM KIND, either express or implied. See the License for the
|
||||||
|
@REM specific language governing permissions and limitations
|
||||||
|
@REM under the License.
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
@REM Maven Start Up Batch script
|
||||||
|
@REM
|
||||||
|
@REM Required ENV vars:
|
||||||
|
@REM JAVA_HOME - location of a JDK home dir
|
||||||
|
@REM
|
||||||
|
@REM Optional ENV vars
|
||||||
|
@REM M2_HOME - location of maven2's installed home dir
|
||||||
|
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||||
|
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
|
||||||
|
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||||
|
@REM e.g. to debug Maven itself, use
|
||||||
|
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||||
|
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||||
|
@echo off
|
||||||
|
@REM set title of command window
|
||||||
|
title %0
|
||||||
|
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
||||||
|
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||||
|
|
||||||
|
@REM set %HOME% to equivalent of $HOME
|
||||||
|
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||||
|
|
||||||
|
@REM Execute a user defined script before this one
|
||||||
|
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||||
|
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||||
|
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
|
||||||
|
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
|
||||||
|
:skipRcPre
|
||||||
|
|
||||||
|
@setlocal
|
||||||
|
|
||||||
|
set ERROR_CODE=0
|
||||||
|
|
||||||
|
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||||
|
@setlocal
|
||||||
|
|
||||||
|
@REM ==== START VALIDATION ====
|
||||||
|
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Error: JAVA_HOME not found in your environment. >&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||||
|
echo location of your Java installation. >&2
|
||||||
|
echo.
|
||||||
|
goto error
|
||||||
|
|
||||||
|
:OkJHome
|
||||||
|
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||||
|
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||||
|
echo location of your Java installation. >&2
|
||||||
|
echo.
|
||||||
|
goto error
|
||||||
|
|
||||||
|
@REM ==== END VALIDATION ====
|
||||||
|
|
||||||
|
:init
|
||||||
|
|
||||||
|
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||||
|
@REM Fallback to current working directory if not found.
|
||||||
|
|
||||||
|
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||||
|
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||||
|
|
||||||
|
set EXEC_DIR=%CD%
|
||||||
|
set WDIR=%EXEC_DIR%
|
||||||
|
:findBaseDir
|
||||||
|
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||||
|
cd ..
|
||||||
|
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||||
|
set WDIR=%CD%
|
||||||
|
goto findBaseDir
|
||||||
|
|
||||||
|
:baseDirFound
|
||||||
|
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||||
|
cd "%EXEC_DIR%"
|
||||||
|
goto endDetectBaseDir
|
||||||
|
|
||||||
|
:baseDirNotFound
|
||||||
|
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||||
|
cd "%EXEC_DIR%"
|
||||||
|
|
||||||
|
:endDetectBaseDir
|
||||||
|
|
||||||
|
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||||
|
|
||||||
|
@setlocal EnableExtensions EnableDelayedExpansion
|
||||||
|
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||||
|
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||||
|
|
||||||
|
:endReadAdditionalConfig
|
||||||
|
|
||||||
|
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||||
|
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||||
|
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||||
|
|
||||||
|
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
||||||
|
|
||||||
|
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||||
|
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||||
|
)
|
||||||
|
|
||||||
|
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||||
|
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||||
|
if exist %WRAPPER_JAR% (
|
||||||
|
if "%MVNW_VERBOSE%" == "true" (
|
||||||
|
echo Found %WRAPPER_JAR%
|
||||||
|
)
|
||||||
|
) else (
|
||||||
|
if not "%MVNW_REPOURL%" == "" (
|
||||||
|
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
||||||
|
)
|
||||||
|
if "%MVNW_VERBOSE%" == "true" (
|
||||||
|
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||||
|
echo Downloading from: %DOWNLOAD_URL%
|
||||||
|
)
|
||||||
|
|
||||||
|
powershell -Command "&{"^
|
||||||
|
"$webclient = new-object System.Net.WebClient;"^
|
||||||
|
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||||
|
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||||
|
"}"^
|
||||||
|
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
|
||||||
|
"}"
|
||||||
|
if "%MVNW_VERBOSE%" == "true" (
|
||||||
|
echo Finished downloading %WRAPPER_JAR%
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@REM End of extension
|
||||||
|
|
||||||
|
@REM Provide a "standardized" way to retrieve the CLI args that will
|
||||||
|
@REM work with both Windows and non-Windows executions.
|
||||||
|
set MAVEN_CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
%MAVEN_JAVA_EXE% ^
|
||||||
|
%JVM_CONFIG_MAVEN_PROPS% ^
|
||||||
|
%MAVEN_OPTS% ^
|
||||||
|
%MAVEN_DEBUG_OPTS% ^
|
||||||
|
-classpath %WRAPPER_JAR% ^
|
||||||
|
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
|
||||||
|
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||||
|
if ERRORLEVEL 1 goto error
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:error
|
||||||
|
set ERROR_CODE=1
|
||||||
|
|
||||||
|
:end
|
||||||
|
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||||
|
|
||||||
|
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
|
||||||
|
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||||
|
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
|
||||||
|
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
|
||||||
|
:skipRcPost
|
||||||
|
|
||||||
|
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||||
|
if "%MAVEN_BATCH_PAUSE%"=="on" pause
|
||||||
|
|
||||||
|
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
|
||||||
|
|
||||||
|
cmd /C exit /B %ERROR_CODE%
|
|
@ -0,0 +1,122 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.7.8</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>kr.gmtc.gw</groupId>
|
||||||
|
<!-- <artifactId>socket</artifactId> -->
|
||||||
|
<artifactId>asderecv</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>EyeGW_AsdeRecv</name>
|
||||||
|
<description>Demo project for Spring Boot</description>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>local-repository</id>
|
||||||
|
<name>local-repository</name>
|
||||||
|
<url>file:${project.basedir}/lib</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!-- <dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency> -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<!-- <exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-logging</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions> -->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 서버간 상태 체크 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>kr.gmt.so</groupId>
|
||||||
|
<artifactId>state-spring-boot-starter</artifactId>
|
||||||
|
<version>1.0.3</version>
|
||||||
|
<scope>system</scope>
|
||||||
|
<systemPath>${basedir}/lib/state-spring-boot-starter-1.0.3.jar</systemPath>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- <dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency> -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.24</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- @Resource 사용 -->
|
||||||
|
<!-- <dependency>
|
||||||
|
<groupId>javax.annotation</groupId>
|
||||||
|
<artifactId>javax.annotation-api</artifactId>
|
||||||
|
<version>1.3.2</version>
|
||||||
|
</dependency> -->
|
||||||
|
|
||||||
|
<!-- IPWorks -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>ipworks.local</groupId>
|
||||||
|
<artifactId>ipworks-local-1.0.0</artifactId>
|
||||||
|
<scope>system</scope>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<systemPath>${basedir}/lib/ipworks/local/1.0.0/ipworks-local-1.0.0.jar</systemPath>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- guava - RateLimiter -->
|
||||||
|
<!-- <dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>31.1-jre</version>
|
||||||
|
</dependency> -->
|
||||||
|
|
||||||
|
<!-- data format -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.yaml</groupId>
|
||||||
|
<artifactId>snakeyaml</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.googlecode.json-simple</groupId>
|
||||||
|
<artifactId>json-simple</artifactId>
|
||||||
|
<version>1.1.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>EyeGW_AsdeRecv-0.0.1</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<includeSystemScope>true</includeSystemScope>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,49 @@
|
||||||
|
package kr.gmtc.gw.asderecv;
|
||||||
|
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.context.ApplicationPidFileWriter;
|
||||||
|
import org.springframework.boot.system.ApplicationHome;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
|
@EnableScheduling
|
||||||
|
@SpringBootApplication
|
||||||
|
public class AsdeRecvApplication {
|
||||||
|
// implements CommandLineRunner
|
||||||
|
// @Autowired
|
||||||
|
// private ApplicationContext appContext;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
//SpringApplication.run(SocketApplication.class, args);
|
||||||
|
ApplicationHome home = new ApplicationHome(AsdeRecvApplication.class);
|
||||||
|
String root = home.getDir().getPath();
|
||||||
|
|
||||||
|
System.setProperty("user.dir", root);
|
||||||
|
|
||||||
|
TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.of("UTC")));
|
||||||
|
|
||||||
|
Thread.currentThread().setName("JVM - Main");
|
||||||
|
|
||||||
|
SpringApplication springApplication = new SpringApplication(AsdeRecvApplication.class);
|
||||||
|
|
||||||
|
springApplication.addListeners(new ApplicationPidFileWriter("./application.pid"));
|
||||||
|
springApplication.run(args);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public void run(String...args) throws Exception {
|
||||||
|
|
||||||
|
// String [] beans = appContext.getBeanDefinitionNames();
|
||||||
|
// Arrays.sort(beans);
|
||||||
|
// for(String bean : beans ){
|
||||||
|
// System.out.println(bean);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/****************************************************************************
|
||||||
|
|
||||||
|
[asterixList.xml] spec file list
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
package kr.gmtc.gw.asderecv.asde.asterixSpec;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
@XmlRootElement(name = "AsterixListCategory")
|
||||||
|
public class AsterixList_Category
|
||||||
|
{
|
||||||
|
private List<AsterixList_SpecFile> asterixFile;
|
||||||
|
|
||||||
|
@XmlElement(name = "AsterixSpecFile")
|
||||||
|
public void setAsterixs(List<AsterixList_SpecFile> asterixFile) {
|
||||||
|
this.asterixFile = asterixFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AsterixList_SpecFile> getAsterixs() {
|
||||||
|
return this.asterixFile;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/****************************************************************************
|
||||||
|
|
||||||
|
[asterixList.xml] spec file 경로 정보
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
package kr.gmtc.gw.asderecv.asde.asterixSpec;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAttribute;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
@XmlRootElement(name = "AsterixSpecFile")
|
||||||
|
public class AsterixList_SpecFile
|
||||||
|
{
|
||||||
|
private String category;
|
||||||
|
private String file;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "category")
|
||||||
|
public void setCategory(String category) {
|
||||||
|
this.category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCategory() {
|
||||||
|
return this.category;
|
||||||
|
}
|
||||||
|
|
||||||
|
@XmlAttribute(name = "file")
|
||||||
|
public void setFile(String file) {
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFile() {
|
||||||
|
return this.file;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
package kr.gmtc.gw.asderecv.asde.asterixSpec;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.bind.JAXBContext;
|
||||||
|
import javax.xml.bind.Unmarshaller;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import kr.gmtc.gw.asderecv.asde.asterixSpec.vo.AsterixSpecVO;
|
||||||
|
import kr.gmtc.gw.asderecv.asde.utils.YamlFileLoader;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
|
||||||
|
asterixList.xml에 정의 되어 있는 모든 spec 파일을 로드하여 specMap에 가지고있고
|
||||||
|
instance를 생성한 클레스에서 getSpec()을 통해 로드된 spec을 가져갈 수 있음.
|
||||||
|
|
||||||
|
사용예)
|
||||||
|
String sCatNo = "10";
|
||||||
|
AsterixSpec asterixSpec = new AsterixSpec();
|
||||||
|
SpecDepth1Category currentSpec = asterixSpec.getSpec(sCatNo);
|
||||||
|
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
public class AsterixSpecLoader
|
||||||
|
{
|
||||||
|
private Logger logger;
|
||||||
|
|
||||||
|
// category별 spec
|
||||||
|
private LinkedHashMap<String, AsterixSpecVO> specMap;
|
||||||
|
|
||||||
|
public AsterixSpecLoader() {
|
||||||
|
initCategory();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initCategory()
|
||||||
|
{
|
||||||
|
|
||||||
|
this.specMap = new LinkedHashMap<String, AsterixSpecVO>();
|
||||||
|
|
||||||
|
AsterixList_Category target;
|
||||||
|
|
||||||
|
this.logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
logger.info("Initializing.. ");
|
||||||
|
// 분석해야 할 Asterix Spec 파일 목록 로드 (resource/asterixList.xml)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
JAXBContext context = JAXBContext.newInstance(AsterixList_Category.class);
|
||||||
|
Unmarshaller umarshaller = context.createUnmarshaller();
|
||||||
|
InputStream is = this.getClass().getClassLoader().getResourceAsStream("asterixList.xml");
|
||||||
|
target = (AsterixList_Category)umarshaller.unmarshal(is);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
logger.error("initCategory- Spec List 로드 실패");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(target == null) {
|
||||||
|
logger.error("initCategory- Spec List 로드 실패(target=null)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<AsterixList_SpecFile> spacList = target.getAsterixs();
|
||||||
|
|
||||||
|
// category별로 상이한 spec내용을 로드 (cat-10, cat-11, ...)
|
||||||
|
for(int i=0;i<spacList.size(); i++)
|
||||||
|
{
|
||||||
|
AsterixList_SpecFile as = spacList.get(i);
|
||||||
|
String catNo = as.getCategory();
|
||||||
|
String file = as.getFile();
|
||||||
|
|
||||||
|
AsterixSpecVO category = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
category = getAsterixCategoryBySpec(file);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("객체생성 실패.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.specMap.put(catNo, category);
|
||||||
|
|
||||||
|
logger.info("Category-" + catNo + " Spec 로드 성공 (파일:" + file + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("initialized. .. ");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private AsterixSpecVO getAsterixCategoryBySpec(String sFile) throws IOException
|
||||||
|
{
|
||||||
|
String sPath = "";
|
||||||
|
|
||||||
|
if(sFile == null) return null;
|
||||||
|
|
||||||
|
sPath = sPath.concat(sFile);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
YamlFileLoader yamLoader = new YamlFileLoader();
|
||||||
|
|
||||||
|
AsterixSpecVO category = yamLoader.yamlLoadToVo(sPath, AsterixSpecVO.class);
|
||||||
|
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public AsterixSpecVO getSpec(String catNo) {
|
||||||
|
return this.specMap.get(catNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/****************************************************************************
|
||||||
|
|
||||||
|
spec(yml)파일의 최상위 노드 cat,ver,dataitem
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
package kr.gmtc.gw.asderecv.asde.asterixSpec.vo;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class AsterixSpecVO implements Serializable
|
||||||
|
{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -4054898835970748785L;
|
||||||
|
|
||||||
|
private String cat;
|
||||||
|
private String ver;
|
||||||
|
private List<AsterixSpecVO_DataItem> dataitem;
|
||||||
|
|
||||||
|
public String getCat() {
|
||||||
|
return cat;
|
||||||
|
}
|
||||||
|
public void setCat(String cat) {
|
||||||
|
this.cat = cat;
|
||||||
|
}
|
||||||
|
public String getVer() {
|
||||||
|
return ver;
|
||||||
|
}
|
||||||
|
public void setVer(String ver) {
|
||||||
|
this.ver = ver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("dataitem")
|
||||||
|
public List<AsterixSpecVO_DataItem> getDataitem() {
|
||||||
|
return dataitem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("dataitem")
|
||||||
|
public void setDataitem(List<AsterixSpecVO_DataItem> dataitem) {
|
||||||
|
this.dataitem = dataitem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/****************************************************************************
|
||||||
|
|
||||||
|
spec(yml)파일의 dataitem.Itemno.structure.name 하위 노드 "codes..."
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
package kr.gmtc.gw.asderecv.asde.asterixSpec.vo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class AsterixSpecVO_Codes
|
||||||
|
{
|
||||||
|
|
||||||
|
private Map<String, String> codes = new HashMap<String, String>();
|
||||||
|
|
||||||
|
|
||||||
|
@JsonAnyGetter
|
||||||
|
public Map<String, String> getCodes() {
|
||||||
|
return this.codes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setCodes(Map<String, String> codes) {
|
||||||
|
this.codes = codes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonAnySetter
|
||||||
|
public void addValue(String key, String value) {
|
||||||
|
this.codes.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
/****************************************************************************
|
||||||
|
|
||||||
|
spec(yml)파일의 dataitem 하위 노드 "-Itemno..."
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
package kr.gmtc.gw.asderecv.asde.asterixSpec.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class AsterixSpecVO_DataItem implements Serializable
|
||||||
|
{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -11726258863773521L;
|
||||||
|
|
||||||
|
private String itemno;
|
||||||
|
private String frn;
|
||||||
|
private String rule;
|
||||||
|
private String itemdesc;
|
||||||
|
private String definition;
|
||||||
|
private String octet;
|
||||||
|
|
||||||
|
private String format;
|
||||||
|
|
||||||
|
private List<AsterixSpecVO_Structure> structure;
|
||||||
|
|
||||||
|
private String dataItemNote;
|
||||||
|
|
||||||
|
public String getItemno() {
|
||||||
|
return itemno;
|
||||||
|
}
|
||||||
|
public void setItemno(String itemno) {
|
||||||
|
this.itemno = itemno;
|
||||||
|
}
|
||||||
|
public String getFrn() {
|
||||||
|
return frn;
|
||||||
|
}
|
||||||
|
public void setFrn(String frn) {
|
||||||
|
this.frn = frn;
|
||||||
|
}
|
||||||
|
public String getItemdesc() {
|
||||||
|
return itemdesc;
|
||||||
|
}
|
||||||
|
public void setItemdesc(String itemdesc) {
|
||||||
|
this.itemdesc = itemdesc;
|
||||||
|
}
|
||||||
|
public String getDefinition() {
|
||||||
|
return definition;
|
||||||
|
}
|
||||||
|
public void setDefinition(String definition) {
|
||||||
|
this.definition = definition;
|
||||||
|
}
|
||||||
|
public String getOctet() {
|
||||||
|
return octet;
|
||||||
|
}
|
||||||
|
public void setOctet(String octet) {
|
||||||
|
this.octet = octet;
|
||||||
|
}
|
||||||
|
public String getFormat() {
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
public void setFormat(String format) {
|
||||||
|
this.format = format;
|
||||||
|
}
|
||||||
|
public List<AsterixSpecVO_Structure> getStructure() {
|
||||||
|
return structure;
|
||||||
|
}
|
||||||
|
public void setStructure(List<AsterixSpecVO_Structure> structure) {
|
||||||
|
this.structure = structure;
|
||||||
|
}
|
||||||
|
public String getDataItemNote() {
|
||||||
|
return dataItemNote;
|
||||||
|
}
|
||||||
|
public void setDataItemNote(String dataItemNote) {
|
||||||
|
this.dataItemNote = dataItemNote;
|
||||||
|
}
|
||||||
|
public String getRule() {
|
||||||
|
|
||||||
|
if(this.rule == null) {
|
||||||
|
return rule = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
|
public void setRule(String rule) {
|
||||||
|
this.rule = rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
/****************************************************************************
|
||||||
|
|
||||||
|
spec(yml)파일의 dataitem.Itemno 하위 노드 "structure..."
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
package kr.gmtc.gw.asderecv.asde.asterixSpec.vo;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class AsterixSpecVO_Structure implements Serializable
|
||||||
|
{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -4804047491424671870L;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String procseq;
|
||||||
|
|
||||||
|
private String frombit;
|
||||||
|
private String tobit;
|
||||||
|
private String desc;
|
||||||
|
private String resolution;
|
||||||
|
private String datatype;
|
||||||
|
private String unit;
|
||||||
|
private AsterixSpecVO_Codes codes;
|
||||||
|
|
||||||
|
private String min;
|
||||||
|
private String max;
|
||||||
|
|
||||||
|
private String serviceFieldName;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProcseq() {
|
||||||
|
return procseq;
|
||||||
|
}
|
||||||
|
public void setProcseq(String procseq) {
|
||||||
|
this.procseq = procseq;
|
||||||
|
}
|
||||||
|
public String getFrombit() {
|
||||||
|
return frombit;
|
||||||
|
}
|
||||||
|
public void setFrombit(String frombit) {
|
||||||
|
this.frombit = frombit;
|
||||||
|
}
|
||||||
|
public String getTobit() {
|
||||||
|
|
||||||
|
if(this.tobit == null) {
|
||||||
|
return this.frombit;
|
||||||
|
}else {
|
||||||
|
return tobit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public void setTobit(String tobit) {
|
||||||
|
this.tobit = tobit;
|
||||||
|
}
|
||||||
|
public String getDesc() {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
public void setDesc(String desc) {
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
public String getResolution() {
|
||||||
|
return resolution;
|
||||||
|
}
|
||||||
|
public void setResolution(String resolution) {
|
||||||
|
this.resolution = resolution;
|
||||||
|
}
|
||||||
|
public String getDatatype() {
|
||||||
|
if(this.datatype == null) {
|
||||||
|
return datatype = "uint";
|
||||||
|
}else {
|
||||||
|
return datatype;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public void setDatatype(String datatype) {
|
||||||
|
this.datatype = datatype;
|
||||||
|
}
|
||||||
|
public String getUnit() {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
public void setUnit(String unit) {
|
||||||
|
this.unit = unit;
|
||||||
|
}
|
||||||
|
public AsterixSpecVO_Codes getCodes() {
|
||||||
|
return codes;
|
||||||
|
}
|
||||||
|
public void setCodes(AsterixSpecVO_Codes codes) {
|
||||||
|
this.codes = codes;
|
||||||
|
}
|
||||||
|
public String getMin() {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
public void setMin(String min) {
|
||||||
|
this.min = min;
|
||||||
|
}
|
||||||
|
public String getMax() {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
public void setMax(String max) {
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
public String getServiceFieldName() {
|
||||||
|
return serviceFieldName;
|
||||||
|
}
|
||||||
|
public void setServiceFieldName(String serviceFieldName) {
|
||||||
|
this.serviceFieldName = serviceFieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,133 @@
|
||||||
|
package kr.gmtc.gw.asderecv.asde.parser;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Queue;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import kr.gmtc.gw.asderecv.rest.vo.ServiceAsdeData;
|
||||||
|
|
||||||
|
public class AsterixParserThread {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
private AsterixParser asterixParser;
|
||||||
|
|
||||||
|
private boolean isRunning = true;
|
||||||
|
private Thread thread;
|
||||||
|
|
||||||
|
private Integer scvQcount = 3;
|
||||||
|
private String debugLogMode = "none";
|
||||||
|
|
||||||
|
List<ServiceAsdeData> serviceMap;
|
||||||
|
|
||||||
|
ObjectMapper mapper;
|
||||||
|
|
||||||
|
DateTimeFormatter dfPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public AsterixParserThread(Queue<String> packetQ, HashMap<Integer, Queue<ServiceAsdeData>> serviceQueue) {
|
||||||
|
thread = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (isRunning) {
|
||||||
|
String packetMsg = "";
|
||||||
|
try {
|
||||||
|
packetMsg = packetQ.poll();
|
||||||
|
|
||||||
|
if (packetMsg != null) {
|
||||||
|
|
||||||
|
// 테스트용
|
||||||
|
//String sBynary = "0A 05 BB E3 81 F1 91 03 8A 06 04 98 3C 00 C1 D9 F5 28 0E 72 45 54 48 33 36 36 37 20 04 01 68 45 54 41 57 45 20 20 20 02 8D 36 34 39 20 00 33 34 52 0B 8F 08 EB 81 71 01 03 02 06 04 98 41 00 D3 95 20 50 08 06 E8 41 46 4C 36 20 20 20 20 71 D1 48 53 49 41 31 34 38 20 20 08 20 EB 81 01 01 03 02 06 04 98 3D C1 CF 75 18 D7 01 00 E0 02 E0 EB 81 71 01 03 02 06 04 98 40 C1 EA EC E5 80 00 00 E8 46 49 52 45 35 20 20 20 71 D1 08 53 49 41 31 30 38 20 20 08 20 EB 81 01 01 03 02 06 04 98 3C 45 E9 6B EC FB 00 00 E0 02 E0 E3 81 81 81 03 02 06 04 98 3F C5 A3 C8 F1 38 06 03 02 AC 00 20 E3 81 81 81 03 02 06 04 98 41 05 46 90 F1 38 06 02 02 6A 00 20 EB 81 F1 91 03 8A 06 04 98 3E 46 E3 86 26 F7 F9 FB F2 07 E3 54 57 42 32 39 32 20 20 71 C3 24 48 4C 38 33 32 34 20 20 3F FE 31 32 39 20 02 33 33 52 04 A7 08 EB 81 F1 11 03 0A 06 04 98 3F 86 D5 73 10 DC FF 00 F8 04 00 4B 41 53 38 20 20 20 20 71 C2 12 48 4C 38 32 31 32 20 20 35 34 36 20 02 04 9A 08 EB 81 01 01 03 02 06 04 98 40 07 CB 78 28 01 00 00 E0 02 E0 EB 81 01 01 03 02 06 04 98 3C CB D6 2D 0F 8A 00 00 E0 02 E0 EB 81 01 01 03 02 06 04 98 3B 8E D3 69 14 D5 00 00 E0 02 E0 EB 81 01 01 03 02 06 04 98 30 51 E8 81 14 CC 00 00 E0 00 E0 EB 81 F1 91 03 8A 06 04 98 3E 12 DA FA 58 54 A1 07 F5 20 08 CF 4B 41 4C 35 35 31 20 20 71 BE 01 48 4C 37 36 30 31 20 20 00 6C 36 30 39 20 00 33 34 52 06 A5 08 E3 81 F1 91 03 8A 06 04 98 3C 14 E4 E6 F5 28 0E 73 41 49 48 32 32 31 20 20 71 C5 03 48 4C 38 35 30 33 20 20 02 73 36 31 36 20 00 33 34 52 05 B4 08 EB 81 F1 91 03 8A 06 04 98 3E 14 D1 26 0E 46 03 02 F2 09 1B 43 53 4E 33 30 36 31 20 78 1D AC 42 33 32 39 53 20 20 20 3F FE 31 32 34 20 02 33 34 4C 04 A6 08 EB 81 01 01 03 02 06 04 98 42 D8 CC 92 18 B2 00 00 E0 00 E0 EB 81 01 01 03 02 06 04 98 35 98 DE 2A 14 0B 00 00 E0 02 E0 EB 81 01 01 03 02 06 04 98 3E DA 0B 2E 16 DE FF 00 E0 00 E0 EB 81 01 01 03 02 06 04 98 40 9A DE FC 21 72 00 00 E0 00 E0 EB 81 01 01 03 02 06 04 98 27 5C D3 D8 32 98 00 00 E0 00 E0 EB 81 F1 91 03 8A 06 04 98 3E 9C D4 72 FA 1A E4 27 F2 07 A8 4B 41 4C 37 35 36 20 20 71 C2 76 48 4C 38 32 37 36 20 20 3F FD 32 34 36 20 02 33 34 4C 04 A8 08 EB 81 01 01 03 02 06 04 98 3F A0 EC 22 01 A7 00 00 E0 02 E0 EB 81 F1 91 83 8A 06 04 98 3E A1 2A 7C CF 65 D6 3B F2 06 BD 4A 4E 41 32 38 32 20 20 71 BF 57 48 4C 37 37 35 37 20 20 00 1D 32 30 20 20 80 71 33 33 52 00 33 33 52 04 A9 08 EB 81 F1 91 03 8A 06 04 98 40 22 05 38 14 50 FC FD F4 0E 70 47 45 43 38 33 39 31 20 3C 70 C9 44 41 4C 46 49 20 20 20 3F FF 36 33 33 20 02 33 34 52 04 23 08 EB 81 01 01 03 02 06 04 98 3F E4 EF 9C 04 0B 00 00 E0 00 E0 EB 81 71 01 03 02 06 04 98 3C E5 D9 E1 09 F9 FD 09 E8 53 41 46 45 54 59 31 20 71 D1 13 53 49 41 31 31 33 20 20 0A 20 EB 81 01 01 03 02 06 04 98 3F E5 EE CB FA B5 00 00 E0 00 E0 EB 81 F1 91 03 8A 06 04 98 3D 66 FE 13 13 E4 08 F5 F2 08 F2 43 59 5A 32 33 31 41 20 78 05 CA 42 32 38 38 31 20 20 20 3F FE 36 30 34 20 02 33 33 52 04 A4 08 EB 81 F1 91 03 8A 06 04 98 3F 66 F8 39 07 39 FB FD F4 0E 63 46 44 58 35 33 39 31 20 AC 25 C4 4E 38 38 32 46 44 20 20 3F FE 36 35 32 20 02 33 34 52 08 97 08 EB 81 E1 81 03 02 06 04 98 3B 28 10 A1 72 50 C4 44 F1 10 00 C1 48 4C 35 32 33 39 20 20 71 AA 39 01 6C 00 20 E3 81 F1 91 03 8A 06 04 98 3E 68 86 EA F5 20 0E 5D 44 4C 48 37 31 39 20 20 3C 67 0E 44 41 49 58 4E 20 20 20 00 6B 33 32 20 20 00 33 34 52 04 24 08 EB 81 01 01 03 02 06 04 98 41 29 CA 2D 1A CC 00 00 E0 02 E0 EB 81 01 01 03 02 06 04 98 39 2A 07 DB 16 5D 00 00 E0 00 E0 EB 81 01 01 03 02 06 04 98 3D ED 0D E0 18 E4 00 00 E0 00 E0 EB 81 01 01 03 02 06 04 98 2A AF CB D2 26 53 00 00 E0 02 E0 EB 81 F1 11 03 02 06 04 98 3A EF 0D 76 04 91 00 00 F2 08 E4 42 33 32 37 37 20 20 20 78 11 D5 42 33 32 37 37 20 20 20 38 34 32 20 02 E0 EB 81 01 01 03 02 06 04 98 3C 2F EA 89 ED 0F 00 00 E0 02 E0 EB 81 01 01 03 02 06 04 98 3B F2 CA 19 24 BF 03 03 E0 02 E0 EB 81 01 01 03 02 06 04 98 41 34 0F 9F 1B C5 00 00 E0 00 E0 EB 81 71 01 03 02 06 04 98 3D B7 01 C9 F6 FB FF FF E8 46 49 52 45 33 20 20 20 71 D1 09 53 49 41 31 30 39 20 20 08 20 EB 81 01 01 03 02 06 04 98 3D F8 D4 C1 12 10 00 00 E0 02 E0 E3 81 81 81 03 02 06 04 98 40 39 4E BC F1 38 06 01 02 44 00 20 EB 81 F1 91 03 8A 06 04 98 3D BA DA EC 01 57 05 F8 F2 06 A6 41 41 52 31 31 31 20 20 71 BF 92 48 4C 37 37 39 32 20 20 3F FE 32 31 20 20 02 33 34 4C 04 A2 08 EB 81 E1 81 03 02 06 04 98 3D BC 13 53 7B 69 C7 58 F1 30 0F 14 4A 4E 41 33 38 30 20 20 71 C0 14 02 29 00 20 EB 81 01 01 03 02 06 04 98 3D 7F 11 2A 1B 1E 00 00 E0 00 E0 ";
|
||||||
|
//sBynary = sBynary.replaceAll("\\p{Z}", "");
|
||||||
|
|
||||||
|
// UDP 수신데이터
|
||||||
|
String sBynary = packetMsg.replaceAll("\\p{Z}", "");
|
||||||
|
String sTime = null;
|
||||||
|
|
||||||
|
// 수신시각
|
||||||
|
if(sBynary.indexOf("*") > 0) {
|
||||||
|
sTime = packetMsg.substring(packetMsg.indexOf("*") +1);
|
||||||
|
sBynary = sBynary.substring(0, sBynary.indexOf("*"));
|
||||||
|
}else {
|
||||||
|
sTime = LocalDateTime.now().format(dfPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 수신 메시지(Hex) byte로 변환
|
||||||
|
byte[] data = new java.math.BigInteger(sBynary, 16).toByteArray();
|
||||||
|
|
||||||
|
// byte문자열 확인
|
||||||
|
// int recvCnt ++;
|
||||||
|
// logger.writeLevelLog("[AsterixParserThread] ByteArray(" + recvCnt + "):" + packetMsg, LogLevelType.LOG_DEBUG, "AllLog");
|
||||||
|
|
||||||
|
// 수신메시지 파싱
|
||||||
|
List<LinkedHashMap<String,String>> result = asterixParser.parse(data, sTime);
|
||||||
|
|
||||||
|
// logger.info("[ASDE분석결과:"+LocalDateTime.now().format(dfPattern)+"] result = "+ result);
|
||||||
|
//logger.info("[ASDE분석결과(service):"+LocalDateTime.now().format(dfPattern)+"] serviceMap = "+ Arrays.deepToString(serviceMap.toArray()));
|
||||||
|
|
||||||
|
if(!serviceMap.isEmpty()) {
|
||||||
|
|
||||||
|
for(int idx=0; idx<serviceMap.size(); idx++) {
|
||||||
|
for(int qi=0; qi<scvQcount; qi++) {
|
||||||
|
serviceQueue.get(qi).offer(serviceMap.get(idx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (e.getMessage() != null) {
|
||||||
|
logger.error("Parsing Error Message : " + e);
|
||||||
|
logger.error("=> Packet Message : " + packetMsg);
|
||||||
|
} else {
|
||||||
|
logger.error("Parsing Error Packet Message :" + packetMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
|
||||||
|
serviceMap = new ArrayList<ServiceAsdeData>();
|
||||||
|
|
||||||
|
// Asterix Parser 객체 생성 (category별로 상이한 yaml파일의 spec내용을 로드)
|
||||||
|
asterixParser = new AsterixParser(serviceMap);
|
||||||
|
asterixParser.setDebugLogMode(debugLogMode);
|
||||||
|
|
||||||
|
mapper = new ObjectMapper();
|
||||||
|
|
||||||
|
isRunning = true;
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop(){
|
||||||
|
isRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScvQcount(Integer scvQcount) {
|
||||||
|
this.scvQcount = scvQcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDebugLogMode(String debugLogMode) {
|
||||||
|
this.debugLogMode = debugLogMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,571 @@
|
||||||
|
package kr.gmtc.gw.asderecv.asde.utils;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import kr.gmtc.gw.asderecv.asde.asterixSpec.vo.AsterixSpecVO;
|
||||||
|
import kr.gmtc.gw.asderecv.asde.asterixSpec.vo.AsterixSpecVO_DataItem;
|
||||||
|
import kr.gmtc.gw.asderecv.asde.asterixSpec.vo.AsterixSpecVO_Structure;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class AsterixParserUtils
|
||||||
|
{
|
||||||
|
private Logger logger = LoggerFactory.getLogger(AsterixParserUtils.class);
|
||||||
|
|
||||||
|
private double AVG_ERAD_NM = 6371.0 / 1.852;
|
||||||
|
private double DE2RA = 0.017453292519943295;
|
||||||
|
private double RA2DE = 57.295779513082323;
|
||||||
|
private double GPI = 3.14159265359;
|
||||||
|
|
||||||
|
public double CONST_BASE_LAT = 37.454228;
|
||||||
|
public double CONST_BASE_LON = 126.460915;
|
||||||
|
|
||||||
|
///////////////////**************************//////////////////////////
|
||||||
|
|
||||||
|
public AsterixSpecVO_DataItem findAsterixDataItem(int idx, AsterixSpecVO spec)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<AsterixSpecVO_DataItem> di = spec.getDataitem();
|
||||||
|
if(di == null) return null;
|
||||||
|
String idxString = String.valueOf(idx);
|
||||||
|
|
||||||
|
for(int i=0; i < di.size(); i++)
|
||||||
|
{
|
||||||
|
AsterixSpecVO_DataItem d = di.get(i);
|
||||||
|
if(d.getFrn().equals(idxString))
|
||||||
|
{
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
logger.error("Exception:" + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String byteToString(int b)
|
||||||
|
{
|
||||||
|
return String.format("0x%02x", b&0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String byteArrayToString(byte[] b)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("0x");
|
||||||
|
for(int i=0; i<b.length; i++)
|
||||||
|
{
|
||||||
|
sb.append(String.format("%02x", b[i]&0xff));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int unsignedToInt(byte[] data)
|
||||||
|
{
|
||||||
|
int val = 0;
|
||||||
|
int len = data.length;
|
||||||
|
|
||||||
|
if(len > 4) {
|
||||||
|
throw new RuntimeException("Too big to convert to integer");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<len; i++)
|
||||||
|
{
|
||||||
|
val = val << 8;
|
||||||
|
val = val | (data[i] & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long unsignedToInt64(byte[] data)
|
||||||
|
{
|
||||||
|
int val = 0;
|
||||||
|
int len = data.length;
|
||||||
|
|
||||||
|
if(len > 8) {
|
||||||
|
throw new RuntimeException("Too big to convert to integer");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<len; i++)
|
||||||
|
{
|
||||||
|
val = val << 8;
|
||||||
|
val = val | (data[i] & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int signedToInt(byte[] data)
|
||||||
|
{
|
||||||
|
return (new java.math.BigInteger(data)).intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final int signedToInt_withSignBit(byte[] data)
|
||||||
|
{
|
||||||
|
|
||||||
|
String sVal = "";
|
||||||
|
|
||||||
|
int sign = 0;
|
||||||
|
int iRetVal = 0;
|
||||||
|
|
||||||
|
int len = data.length;
|
||||||
|
|
||||||
|
if(len > 4) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<len; i++)
|
||||||
|
{
|
||||||
|
sVal = sVal.concat(String.format("%08d", Integer.parseInt(Integer.toBinaryString(data[i] & 0xff))));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sign = Integer.parseInt(sVal.substring(0, 1));
|
||||||
|
iRetVal = Integer.parseInt(sVal.substring(1), 2);
|
||||||
|
|
||||||
|
if(sign == 1) iRetVal = -(iRetVal);
|
||||||
|
|
||||||
|
return iRetVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int signedToInt_withSignBit_1byte(byte data)
|
||||||
|
{
|
||||||
|
|
||||||
|
String sVal = "";
|
||||||
|
|
||||||
|
int sign = 0;
|
||||||
|
int iRetVal = 0;
|
||||||
|
|
||||||
|
sVal = String.format("%08d", Integer.parseInt(Integer.toBinaryString(data & 0xff)));
|
||||||
|
|
||||||
|
sign = Integer.parseInt(sVal.substring(0, 1));
|
||||||
|
iRetVal = Integer.parseInt(sVal.substring(1), 2);
|
||||||
|
|
||||||
|
if(sign == 1) iRetVal = -(iRetVal);
|
||||||
|
|
||||||
|
return iRetVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
private StringBuffer makeString(StringBuffer sb, int val)
|
||||||
|
{
|
||||||
|
sb.append(val);
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOctetSeq(byte[] target, int bit)
|
||||||
|
{
|
||||||
|
if(target == null || target.length == 0) return -1;
|
||||||
|
|
||||||
|
int size = target.length;
|
||||||
|
int msb = size * 8;
|
||||||
|
int octetSeq = 1;
|
||||||
|
|
||||||
|
for(octetSeq = 1; octetSeq<=size; octetSeq++)
|
||||||
|
{
|
||||||
|
msb -= 8;
|
||||||
|
if(bit > msb) return octetSeq;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String makeOctal(byte[] buf)
|
||||||
|
{
|
||||||
|
if(buf == null || buf.length != 2) return "";
|
||||||
|
|
||||||
|
int num = buf[0] & 0xff;
|
||||||
|
int num2 = buf[1];
|
||||||
|
int n = buf[0] & 0x0f;
|
||||||
|
n = n >>> 1;
|
||||||
|
|
||||||
|
StringBuffer sbuffer = new StringBuffer();
|
||||||
|
sbuffer = makeString(sbuffer, n);
|
||||||
|
|
||||||
|
n = ((num2 >>> 6) & 0x03) | ((num & 0x01) << 2);
|
||||||
|
|
||||||
|
sbuffer = makeString(sbuffer, n);
|
||||||
|
|
||||||
|
n = ((num2 >>> 3) & 0x07);
|
||||||
|
sbuffer = makeString(sbuffer, n);
|
||||||
|
|
||||||
|
n = num2 & 0x07;
|
||||||
|
sbuffer = makeString(sbuffer, n);
|
||||||
|
|
||||||
|
return sbuffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String makeICAOCode(byte[] buf)
|
||||||
|
{
|
||||||
|
if(buf == null || buf.length != 6) return "";
|
||||||
|
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
int octet1 = buf[0];
|
||||||
|
octet1 = octet1 & 0xff;
|
||||||
|
|
||||||
|
octet1 = octet1 >>> 2;
|
||||||
|
sb = makeTargetIdentification(sb, octet1);
|
||||||
|
|
||||||
|
octet1 = buf[0];
|
||||||
|
octet1 = octet1 & 0xff;
|
||||||
|
int octet2 = buf[1];
|
||||||
|
octet2 = octet2 & 0xff;
|
||||||
|
octet2 = octet2 >>> 4;
|
||||||
|
|
||||||
|
octet1 = octet1 << 4;
|
||||||
|
octet1 = octet1 & 0x30;
|
||||||
|
int number = octet1 | octet2;
|
||||||
|
sb = makeTargetIdentification(sb, number);
|
||||||
|
|
||||||
|
octet1 = buf[1] & 0xff;
|
||||||
|
octet2 = buf[2] & 0xff;
|
||||||
|
|
||||||
|
octet1 = octet1 << 2;
|
||||||
|
octet1 = octet1 & 0x3f;
|
||||||
|
octet2 = octet2 >>> 6;
|
||||||
|
|
||||||
|
number = octet1 | octet2;
|
||||||
|
sb = makeTargetIdentification(sb, number);
|
||||||
|
|
||||||
|
octet1 = buf[2];
|
||||||
|
number = octet1 & 0x3f;
|
||||||
|
sb = makeTargetIdentification(sb, number);
|
||||||
|
|
||||||
|
octet1 = buf[3];
|
||||||
|
octet1 = octet1 & 0xff;
|
||||||
|
number = octet1 >>> 2;
|
||||||
|
sb = makeTargetIdentification(sb, number);
|
||||||
|
|
||||||
|
octet1 = buf[3] & 0xff;
|
||||||
|
octet2 = buf[4] & 0xff;
|
||||||
|
|
||||||
|
octet1 = octet1 << 4;
|
||||||
|
octet1 = octet1 & 0x3f;
|
||||||
|
octet2 = octet2 >>> 4;
|
||||||
|
|
||||||
|
number = octet1 | octet2;
|
||||||
|
sb = makeTargetIdentification(sb, number);
|
||||||
|
|
||||||
|
octet1 = buf[4] & 0xff;
|
||||||
|
octet2 = buf[5] & 0xff;
|
||||||
|
|
||||||
|
octet1 = octet1 << 2;
|
||||||
|
octet1 = octet1 & 0x3f;
|
||||||
|
octet2 = octet2 >>> 6;
|
||||||
|
|
||||||
|
number = octet1 | octet2;
|
||||||
|
sb = makeTargetIdentification(sb, number);
|
||||||
|
|
||||||
|
octet1 = buf[5];
|
||||||
|
number = octet1 & 0x3f;
|
||||||
|
sb = makeTargetIdentification(sb, number);
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String makeAscii(byte[] buf)
|
||||||
|
{
|
||||||
|
String retVal = "";
|
||||||
|
|
||||||
|
if(buf == null || buf.length == 0) return "";
|
||||||
|
|
||||||
|
retVal = new String(buf);
|
||||||
|
|
||||||
|
return retVal.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String zeroPadding2digitAtFront(int number)
|
||||||
|
{
|
||||||
|
if(number <= 0) return "01";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String str = String.valueOf(number);
|
||||||
|
int length = str.length();
|
||||||
|
|
||||||
|
if(length >= 2) return str;
|
||||||
|
else return "0" + str;
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
logger.error("Exception:" + e);
|
||||||
|
return "01";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private StringBuffer makeTargetIdentification(StringBuffer sb, int val)
|
||||||
|
{
|
||||||
|
if(val == 0) return sb;
|
||||||
|
else if(val == 32)
|
||||||
|
{
|
||||||
|
sb.append(" ");
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
else if(val >= 1 && val <= 26)
|
||||||
|
{
|
||||||
|
sb.append(Character.toChars(64 + val));
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
else if(val >= 48 && val <= 57)
|
||||||
|
{
|
||||||
|
sb.append(Character.toChars(val));
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
else return sb;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////**************************//////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public String prtbyteToCnv(byte[] byteData, int flag) {
|
||||||
|
String retStr = "";
|
||||||
|
|
||||||
|
String toHex = "";
|
||||||
|
|
||||||
|
String toByte = Arrays.toString(byteData);
|
||||||
|
|
||||||
|
String toBynary = "";
|
||||||
|
|
||||||
|
String to8bitDec = "";
|
||||||
|
|
||||||
|
for(int idx=0; idx < byteData.length; idx++)
|
||||||
|
{
|
||||||
|
if(!toHex.equals("")) {
|
||||||
|
toHex = toHex.concat(" ");
|
||||||
|
toBynary = toBynary.concat(" ");
|
||||||
|
to8bitDec = to8bitDec.concat(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
toHex = toHex.concat(String.format("%02X", byteData[idx] &0xff));
|
||||||
|
|
||||||
|
toBynary = toBynary.concat(String.format("%08d", Integer.parseInt(Integer.toBinaryString(byteData[idx] &0xff ))));
|
||||||
|
|
||||||
|
to8bitDec = to8bitDec.concat(Integer.toString(byteData[idx] & 0xff));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(flag == 0)
|
||||||
|
retStr = "DATA: " + toHex + " " + toBynary + " " + toByte + " " + to8bitDec;
|
||||||
|
else
|
||||||
|
retStr = "DATA: " + toHex;
|
||||||
|
|
||||||
|
return retStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double calcAngleDegree(double y1, double x1, double y2, double x2) {
|
||||||
|
|
||||||
|
double angle;
|
||||||
|
double dx;
|
||||||
|
double dy;
|
||||||
|
|
||||||
|
dx = x2 - x1;
|
||||||
|
dy = y2 - y1;
|
||||||
|
|
||||||
|
// 두점사이의 절대각
|
||||||
|
angle = Math.atan2(dy, dx);
|
||||||
|
|
||||||
|
// ArcTan2 함수의 결과값은 라디안이므로, 도 단위로 변환
|
||||||
|
angle = angle * 180 / Math.PI;
|
||||||
|
|
||||||
|
if (angle < 0)
|
||||||
|
angle = 360 + angle;
|
||||||
|
|
||||||
|
return angle;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public double calcDirection(double Vy, double Vx) {
|
||||||
|
|
||||||
|
double angle;
|
||||||
|
|
||||||
|
// 두점사이의 절대각
|
||||||
|
angle = Math.atan2(Vy, Vx);
|
||||||
|
|
||||||
|
// ArcTan2 함수의 결과값은 라디안이므로, 도 단위로 변환
|
||||||
|
// angle = angle * 180 / Math.PI;
|
||||||
|
//
|
||||||
|
// //if (angle > 160)
|
||||||
|
angle = Math.toDegrees(angle) ;
|
||||||
|
|
||||||
|
if (angle < 0)
|
||||||
|
angle = 360 + angle;
|
||||||
|
|
||||||
|
return angle;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Double> calcDistanceAzimuth(double Lat, double Lon, double DistNM, double Azimuth) {
|
||||||
|
|
||||||
|
double dA;
|
||||||
|
double dB;
|
||||||
|
double dSinb;
|
||||||
|
double dCosb;
|
||||||
|
double dSinc;
|
||||||
|
double dCosc;
|
||||||
|
double dAzrad;
|
||||||
|
double dArcCosValue;
|
||||||
|
double dArcSinValue;
|
||||||
|
|
||||||
|
Map<String, Double> retMap = new HashMap<String, Double>();
|
||||||
|
|
||||||
|
dB = DistNM / AVG_ERAD_NM;
|
||||||
|
dSinb = Math.sin(dB);
|
||||||
|
dCosb = Math.cos(dB);
|
||||||
|
dSinc = Math.sin(DE2RA * (90.0 - Lat));
|
||||||
|
dCosc = Math.cos(DE2RA * (90.0 - Lat));
|
||||||
|
dAzrad = DE2RA * Azimuth;
|
||||||
|
|
||||||
|
dArcCosValue = dCosb * dCosc + dSinc * dSinb * Math.cos(dAzrad);
|
||||||
|
if(dArcCosValue < -1) dArcCosValue = -1;
|
||||||
|
if(dArcCosValue > 1) dArcCosValue = 1;
|
||||||
|
dA = Math.acos(dArcCosValue);
|
||||||
|
|
||||||
|
dArcSinValue = dSinb * Math.sin(dAzrad) / Math.sin(dA);
|
||||||
|
if(dArcSinValue < -1) dArcSinValue = -1;
|
||||||
|
if(dArcSinValue > 1) dArcSinValue = 1;
|
||||||
|
dB = Math.asin(dArcSinValue);
|
||||||
|
|
||||||
|
double outLat = RA2DE * ((GPI/2.0) - dA);
|
||||||
|
double outLon = RA2DE * dB + Lon;
|
||||||
|
|
||||||
|
retMap.put("lat", outLat);
|
||||||
|
retMap.put("lon", outLon);
|
||||||
|
|
||||||
|
return retMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int parseIntDef(String sValue) {
|
||||||
|
|
||||||
|
int defaultValue = 0;
|
||||||
|
|
||||||
|
if (sValue == null) {
|
||||||
|
return defaultValue;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
double dVal = Double.parseDouble(sValue);
|
||||||
|
return (int) dVal;
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public double parseDoubleDef(String sValue) {
|
||||||
|
|
||||||
|
double defaultValue = 0;
|
||||||
|
|
||||||
|
if (sValue == null) {
|
||||||
|
return defaultValue;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
return Double.parseDouble(sValue);
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String prtIntToCnv(int byteData) {
|
||||||
|
|
||||||
|
String retStr = "";
|
||||||
|
|
||||||
|
String toHex = String.format("%02X", byteData &0xff);
|
||||||
|
|
||||||
|
String toByte = Integer.toString(byteData);
|
||||||
|
|
||||||
|
String toBynary = String.format("%08d", Integer.parseInt(Integer.toBinaryString(byteData & 0xff )));
|
||||||
|
|
||||||
|
|
||||||
|
retStr = "DATA: " + toHex + " " + toBynary + " " + toByte + " " + (byteData & 0xff);
|
||||||
|
|
||||||
|
return retStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void printDataLog(String pos, AsterixSpecVO_DataItem di, Map<String, String> map, byte[] data) {
|
||||||
|
|
||||||
|
//logger.writeLevelLog("[parse] [" + di.getItemno() +"] = "+map.get("SPF") + " | " + prtIntToCnv(iSPF) , LogLevelType.LOG_DEBUG, "AllLog");
|
||||||
|
|
||||||
|
String sRetVal = "";
|
||||||
|
String mapName = "", mapData = "";
|
||||||
|
String sHexData = "";
|
||||||
|
|
||||||
|
if(di == null ) return ;
|
||||||
|
|
||||||
|
List<AsterixSpecVO_Structure> struc = di.getStructure();
|
||||||
|
|
||||||
|
|
||||||
|
for(int idx = 0; idx<struc.size(); idx++) {
|
||||||
|
|
||||||
|
mapName = struc.get(idx).getName().toUpperCase();
|
||||||
|
|
||||||
|
mapData = map.get(mapName);
|
||||||
|
|
||||||
|
if(mapData == null) mapData = "N/A";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (!sRetVal.equals("")) sRetVal = sRetVal.concat(", ");
|
||||||
|
|
||||||
|
sRetVal = sRetVal.concat(mapName).concat("=").concat(mapData);
|
||||||
|
}
|
||||||
|
|
||||||
|
sHexData = prtbyteToCnv(data,0);
|
||||||
|
|
||||||
|
sRetVal = sRetVal.concat(" ").concat(sHexData);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// logger.writeLevelLog("[parse-"+pos+"] [" + di.getItemno() +": Bytes:" + di.getOctet() + "] => Parse: "+sRetVal, LogLevelType.LOG_DEBUG, "AllLog");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String cnvBytesToHex(byte[] bArr) {
|
||||||
|
|
||||||
|
String sRetVal = "";
|
||||||
|
int iLen = bArr.length;
|
||||||
|
|
||||||
|
for(int idx = 0; idx<iLen; idx++) {
|
||||||
|
sRetVal = sRetVal.concat(String.format("%02X", bArr[idx] &0xff)).concat(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!sRetVal.equals("")) {
|
||||||
|
sRetVal = "[".concat(sRetVal.substring(0, sRetVal.length() -1)).concat("]");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sRetVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String prtStrucItems(List<AsterixSpecVO_Structure> st, LinkedHashMap<String, String> resMap) {
|
||||||
|
|
||||||
|
// Iterator<Integer> it = st.keySet().iterator();
|
||||||
|
String sRet = "";
|
||||||
|
String sVal = "";
|
||||||
|
|
||||||
|
for(int i=0; i<st.size(); i++)
|
||||||
|
{
|
||||||
|
AsterixSpecVO_Structure struc = st.get(i);
|
||||||
|
String name = struc.getName().toUpperCase();
|
||||||
|
sRet = sRet.concat(name).concat("=");
|
||||||
|
if(resMap.get(name) != null) {
|
||||||
|
sVal = resMap.get(name);
|
||||||
|
}else {
|
||||||
|
sVal = "N/A";
|
||||||
|
}
|
||||||
|
sRet = sRet.concat(sVal).concat(", ");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return sRet ;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package kr.gmtc.gw.asderecv.asde.utils;
|
||||||
|
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public class FieldNameReflectionUtils {
|
||||||
|
|
||||||
|
|
||||||
|
public String getItem(Object obj, String sFieldName) {
|
||||||
|
|
||||||
|
String sRetValue = "";
|
||||||
|
|
||||||
|
Field field = ReflectionUtils.findField(obj.getClass(), sFieldName);
|
||||||
|
|
||||||
|
if(field != null) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
sRetValue = (String) ReflectionUtils.getField(field, obj);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return sRetValue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setItem(Object obj, String sFieldName, String sValue) {
|
||||||
|
|
||||||
|
Field field = ReflectionUtils.findField(obj.getClass(), sFieldName);
|
||||||
|
|
||||||
|
if(field != null) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
ReflectionUtils.setField(field, obj, sValue);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package kr.gmtc.gw.asderecv.asde.utils;
|
||||||
|
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
|
||||||
|
public class YamlFileLoader {
|
||||||
|
|
||||||
|
private Object returnObj;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yamlLoadToVo()
|
||||||
|
* yaml 파일을 JSON포멧으로 로드하여 vo객체로 변환후 리턴
|
||||||
|
*
|
||||||
|
* @param sFile - yaml 파일 경로
|
||||||
|
* @param cVO - yaml파일 내용을 로드하여 담을 VO 클래스
|
||||||
|
* @return Object를 파라메터로 넘어온 VO클래스로 casting하여 반환
|
||||||
|
* @throws Json 포멧의 데이터를 Object로 변환시 오류발생하면 예외발생.
|
||||||
|
* @date 2023.02.07
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public <T> T yamlLoadToVo(String sFile, Class<T> cVO) {
|
||||||
|
|
||||||
|
if(sFile == null || sFile.equals("")) return cVO.cast(returnObj);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
InputStream is = this.getClass().getResourceAsStream("/" + sFile);
|
||||||
|
Reader reader = (is != null ? new InputStreamReader(is) : new FileReader(sFile));
|
||||||
|
|
||||||
|
// yaml 파일 로드
|
||||||
|
//LinkedHashMap<String, Object> propMap = new Yaml().load(new FileReader(ResourceUtils.getFile(sFile)));
|
||||||
|
LinkedHashMap<String, Object> propMap = new Yaml().load(reader);
|
||||||
|
|
||||||
|
// 파일내용을 JSON 포멧으로 변환
|
||||||
|
JSONObject jsonObject = new JSONObject(propMap);
|
||||||
|
|
||||||
|
// JSON 데이터를 Object로 변환
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
// Array Null값, 중간중간 존재하지 않는 필드 무시
|
||||||
|
objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT);
|
||||||
|
objectMapper.configure(DeserializationFeature.FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY, false);
|
||||||
|
|
||||||
|
returnObj = objectMapper.readValue(jsonObject.toJSONString(), cVO);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return cVO.cast(returnObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package kr.gmtc.gw.asderecv.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import kr.gmtc.gw.asderecv.rest.vo.ServiceAsdeData;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
@Configuration("ServiceConfig")
|
||||||
|
public class ServiceConfig {
|
||||||
|
|
||||||
|
@Value("${root}")
|
||||||
|
private String root;
|
||||||
|
|
||||||
|
@Bean(name = "packetQ")
|
||||||
|
public Queue<String> packetQ(){
|
||||||
|
return new LinkedBlockingQueue<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "serviceQueue")
|
||||||
|
public HashMap<Integer, Queue<ServiceAsdeData>> serviceQueue(){
|
||||||
|
return new LinkedHashMap<Integer, Queue<ServiceAsdeData>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "serviceRunnig")
|
||||||
|
public boolean serviceRunnig(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,182 @@
|
||||||
|
package kr.gmtc.gw.asderecv.controller;
|
||||||
|
|
||||||
|
import kr.gmt.so.state.StateManager;
|
||||||
|
import kr.gmt.so.state.callback.IState;
|
||||||
|
import kr.gmtc.gw.asderecv.asde.parser.AsterixParserThread;
|
||||||
|
import kr.gmtc.gw.asderecv.rest.ServiceQueManager;
|
||||||
|
import kr.gmtc.gw.asderecv.rest.vo.ServiceAsdeData;
|
||||||
|
import kr.gmtc.gw.asderecv.utils.CmmnUtil;
|
||||||
|
import kr.gmtc.gw.comp.socket.udp.UDPEventListener;
|
||||||
|
import kr.gmtc.gw.comp.socket.udp.UDPManager;
|
||||||
|
import kr.gmtc.gw.comp.socket.utils.SocketUtil;
|
||||||
|
import kr.gmtc.gw.comp.socket.vo.MsgObjVO;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.context.event.ContextClosedEvent;
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Queue;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
@Component("controller")
|
||||||
|
public class MainController implements ApplicationListener<ContextClosedEvent>{
|
||||||
|
|
||||||
|
Queue<String> packetQ;
|
||||||
|
HashMap<Integer, Queue<ServiceAsdeData>> serviceQueue;
|
||||||
|
|
||||||
|
@Value("${root}")
|
||||||
|
String path;
|
||||||
|
|
||||||
|
@Value("${asde.service.queueCount}")
|
||||||
|
private Integer scvQcount;
|
||||||
|
|
||||||
|
@Value("${asde.service.clearQ.maxCount}")
|
||||||
|
private Integer scvQmaxCount;
|
||||||
|
|
||||||
|
@Value("${asde.service.clearQ.diffTime}")
|
||||||
|
private Integer scvQdiffTime;
|
||||||
|
|
||||||
|
@Value("${asde.service.clearQ.clearTime}")
|
||||||
|
private Integer scvQclearTime;
|
||||||
|
|
||||||
|
@Value("${dev.debug.debugLogMode}")
|
||||||
|
private String debugLogMode = "none";
|
||||||
|
|
||||||
|
@Resource(name = "serviceRunnig")
|
||||||
|
private boolean serviceRunnig = false;
|
||||||
|
|
||||||
|
protected UDPManager udpManager;
|
||||||
|
private UDPEventListener udpListener;
|
||||||
|
|
||||||
|
private AsterixParserThread asterixParserThread;
|
||||||
|
|
||||||
|
private ServiceQueManager serviceQueManager;
|
||||||
|
|
||||||
|
protected Logger logger;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private StateManager stateMgr;
|
||||||
|
|
||||||
|
protected MainController(Queue<String> packetQ, HashMap<Integer, Queue<ServiceAsdeData>> serviceQueue){
|
||||||
|
|
||||||
|
this.packetQ = packetQ;
|
||||||
|
this.serviceQueue = serviceQueue;
|
||||||
|
|
||||||
|
logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Order(0)
|
||||||
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
|
public void initialize() {
|
||||||
|
|
||||||
|
udpListener = createUDPEventListener();
|
||||||
|
udpManager = new UDPManager(path, udpListener);
|
||||||
|
|
||||||
|
asterixParserThread = new AsterixParserThread(packetQ, serviceQueue);
|
||||||
|
asterixParserThread.setScvQcount(scvQcount);
|
||||||
|
asterixParserThread.setDebugLogMode(debugLogMode);
|
||||||
|
|
||||||
|
serviceQueManager = new ServiceQueManager(serviceQueue, serviceRunnig);
|
||||||
|
serviceQueManager.setScvQclearTime(scvQclearTime);
|
||||||
|
serviceQueManager.setScvQcount(scvQcount);
|
||||||
|
serviceQueManager.setScvQdiffTime(scvQdiffTime);
|
||||||
|
serviceQueManager.setScvQmaxCount(scvQmaxCount);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Order(1)
|
||||||
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
|
public void start() {
|
||||||
|
|
||||||
|
udpManager.startClient();
|
||||||
|
serviceQueManager.start();
|
||||||
|
asterixParserThread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void stop() {}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
protected UDPEventListener createUDPEventListener() {
|
||||||
|
UDPEventListener listener = new UDPEventListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void udpDataIn(MsgObjVO vo) {
|
||||||
|
recvPacketAdd(vo);
|
||||||
|
stateMgr.updateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void udpSendData(MsgObjVO vo) {
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'udpSendData'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void udpSendData(String ip, int port, MsgObjVO vo) {
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'udpSendData'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connected(String ip, int port, int statusCode, String description) {
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'connected'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disconnected(String ip, int port, int statusCode, String description) {
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'disconnected'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectionStatus(String ip, int port, String connEvent, int statusCode, String description) {
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'connectionStatus'");
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
return listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void recvPacketAdd(MsgObjVO vo) {
|
||||||
|
|
||||||
|
if (vo.getMsg().length < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
String msg = SocketUtil.byteArrayToHexString(vo.getMsg());
|
||||||
|
|
||||||
|
String recvDate = vo.getRecvDT().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
|
||||||
|
|
||||||
|
msg = msg.concat("*").concat(recvDate);
|
||||||
|
|
||||||
|
packetQ.add(msg);
|
||||||
|
|
||||||
|
//logger.debug("[UDPDataIn] : " + msg);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
logger.error("[MainController] recvPacketAdd Exception " + CmmnUtil.getStatckTrace(e) );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
|
||||||
|
this.stop();
|
||||||
|
logger.info("====================== SYSTEM STOPED ======================");
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package kr.gmtc.gw.asderecv.logger;
|
||||||
|
|
||||||
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
|
import ch.qos.logback.core.AppenderBase;
|
||||||
|
import ch.qos.logback.core.Layout;
|
||||||
|
|
||||||
|
public class CustomAppender extends AppenderBase<ILoggingEvent> {
|
||||||
|
|
||||||
|
static int DEFAULT_LIMIT = 10;
|
||||||
|
int counter = 0;
|
||||||
|
int limit = DEFAULT_LIMIT;
|
||||||
|
|
||||||
|
Layout<ILoggingEvent> layout;
|
||||||
|
|
||||||
|
public void setLimit(int limit) {
|
||||||
|
this.limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLimit() {
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
if (this.layout == null) {
|
||||||
|
addError("No layout set for the appender named [" + name + "].");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String header = layout.getFileHeader();
|
||||||
|
System.out.print(header);
|
||||||
|
super.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void append(ILoggingEvent event) {
|
||||||
|
if (counter >= limit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// output the events as formatted by patternLayout
|
||||||
|
String eventStr = this.layout.doLayout(event);
|
||||||
|
|
||||||
|
System.out.print(eventStr);
|
||||||
|
|
||||||
|
// prepare for next event
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Layout<ILoggingEvent> getLayout() {
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLayout(Layout<ILoggingEvent> layout) {
|
||||||
|
this.layout = layout;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,297 @@
|
||||||
|
package kr.gmtc.gw.asderecv.rest;
|
||||||
|
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
// import com.google.common.util.concurrent.RateLimiter;
|
||||||
|
|
||||||
|
import kr.gmtc.gw.asderecv.rest.vo.SacpServiceVO;
|
||||||
|
import kr.gmtc.gw.asderecv.rest.vo.ServiceAsdeData;
|
||||||
|
import kr.gmtc.gw.asderecv.utils.CmmnUtil;
|
||||||
|
import kr.gmtc.gw.asderecv.rest.vo.SacpServiceHeader;
|
||||||
|
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class AsdeServiceController{
|
||||||
|
|
||||||
|
// 프레임 워크 구성요소 //
|
||||||
|
/** 서비스 설정, {@code application.yml} */
|
||||||
|
// @Resource(name = "ServiceConfig")
|
||||||
|
// private ServiceConfig serviceConfig;
|
||||||
|
|
||||||
|
/* UDP test 소켓 */
|
||||||
|
//UDPEchoClient UDPSocket ;
|
||||||
|
|
||||||
|
@Resource(name = "serviceQueue")
|
||||||
|
HashMap<Integer, Queue<ServiceAsdeData>> serviceQueue;
|
||||||
|
|
||||||
|
@Resource(name = "packetQ")
|
||||||
|
Queue<String> packetQ;
|
||||||
|
|
||||||
|
|
||||||
|
Queue<ServiceAsdeData> testMap = new LinkedBlockingQueue<ServiceAsdeData>();
|
||||||
|
|
||||||
|
/* 서비스중인지 확인 */
|
||||||
|
@Resource(name = "serviceRunnig")
|
||||||
|
private boolean serviceRunnig = false;
|
||||||
|
|
||||||
|
@Value("${asde.service.queueCount}")
|
||||||
|
private Integer scvQcount;
|
||||||
|
|
||||||
|
@Value("${asde.service.serviceCount}")
|
||||||
|
private Integer scvDatacount;
|
||||||
|
|
||||||
|
private SacpServiceVO asdeServiceVO;
|
||||||
|
|
||||||
|
protected Logger logger;
|
||||||
|
|
||||||
|
protected ObjectMapper mapper;
|
||||||
|
|
||||||
|
DateTimeFormatter dfPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
|
||||||
|
|
||||||
|
public AsdeServiceController() {
|
||||||
|
|
||||||
|
logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
mapper = new ObjectMapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/getASDE/{qid}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
public synchronized ResponseEntity<String> getASDE( @PathVariable Integer qid) {
|
||||||
|
|
||||||
|
int qidx = qid -1;
|
||||||
|
|
||||||
|
String sRetJsonData = "";
|
||||||
|
|
||||||
|
// synchronized(serviceQueue.get(qidx)){
|
||||||
|
sRetJsonData = makeServiceData(qidx, serviceQueue.get(qidx));
|
||||||
|
// }
|
||||||
|
|
||||||
|
return ResponseEntity.ok(sRetJsonData);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/getQueCount/{qid}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
public synchronized ResponseEntity<String> getQueCount( @PathVariable Integer qid) {
|
||||||
|
|
||||||
|
int qidx = qid -1;
|
||||||
|
|
||||||
|
String sRetJsonData = "Que Count : ";
|
||||||
|
|
||||||
|
if(qidx == -1){
|
||||||
|
sRetJsonData = sRetJsonData + "[" ;
|
||||||
|
|
||||||
|
for(int idx =0;idx<serviceQueue.size();idx++){
|
||||||
|
sRetJsonData = sRetJsonData + serviceQueue.get(idx).size() + "/" ;
|
||||||
|
}
|
||||||
|
|
||||||
|
sRetJsonData = sRetJsonData + " Que Size:" +serviceQueue.size()+ "]";
|
||||||
|
}else{
|
||||||
|
sRetJsonData = sRetJsonData + "[" + qid + "]" + serviceQueue.get(qidx).size() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseEntity.ok(sRetJsonData);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/getASDE/{qid}/{clsgn}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
public ResponseEntity<String> getASDEFilter( @PathVariable Integer qid, @PathVariable String clsgn) {
|
||||||
|
|
||||||
|
int qidx = qid -1;
|
||||||
|
|
||||||
|
String sRetJsonData = "";
|
||||||
|
|
||||||
|
synchronized(serviceQueue.get(qidx)){
|
||||||
|
sRetJsonData = makeServiceDataFilter(qidx, serviceQueue.get(qidx), clsgn);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseEntity.ok(sRetJsonData);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String makeServiceData(int queIdx, Queue<ServiceAsdeData> procQue){
|
||||||
|
|
||||||
|
String sendCode, sendMsg ;
|
||||||
|
SacpServiceHeader jsonHeader = new SacpServiceHeader();
|
||||||
|
List<ServiceAsdeData> jsonData = new LinkedList<ServiceAsdeData>();
|
||||||
|
|
||||||
|
sendCode = "200";
|
||||||
|
sendMsg = "";
|
||||||
|
|
||||||
|
asdeServiceVO = new SacpServiceVO();
|
||||||
|
|
||||||
|
int qTotalSize = procQue.size();
|
||||||
|
int qSize = qTotalSize;
|
||||||
|
|
||||||
|
if(qSize > scvDatacount) qSize = scvDatacount;
|
||||||
|
|
||||||
|
if(queIdx > scvQcount -1 || queIdx < 0) {
|
||||||
|
sendCode = "Err-01";
|
||||||
|
sendMsg = "할당되지 않은 큐를 지정했습니다.";
|
||||||
|
logger.error(sendMsg);
|
||||||
|
}else {
|
||||||
|
//if(procQue.peek() == null) {
|
||||||
|
if(qSize <= 0) {
|
||||||
|
sendCode = "200";
|
||||||
|
sendMsg = "전송할 데이터 없음.";
|
||||||
|
// logger.error("procQue size" + " / " + procQue.size());
|
||||||
|
}else{
|
||||||
|
|
||||||
|
serviceRunnig = true;
|
||||||
|
|
||||||
|
while (qSize > 0 ) {
|
||||||
|
|
||||||
|
|
||||||
|
ServiceAsdeData data = procQue.poll();
|
||||||
|
|
||||||
|
if( data != null){
|
||||||
|
jsonData.add(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
qSize--;
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceRunnig = false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonHeader.setResult_code(sendCode);
|
||||||
|
jsonHeader.setResult_msg(sendMsg);
|
||||||
|
|
||||||
|
asdeServiceVO.setHeader(jsonHeader);
|
||||||
|
|
||||||
|
if (sendCode.equals("200")) {
|
||||||
|
|
||||||
|
asdeServiceVO.setData(jsonData);
|
||||||
|
|
||||||
|
int iJsonSize = jsonData.size();
|
||||||
|
if(iJsonSize <= 0 ){
|
||||||
|
iJsonSize = 0;
|
||||||
|
logger.info("Que["+(queIdx + 1)+"] service count :" + jsonData.size() + "/" + qTotalSize + "/" + "[분석중:"+packetQ.size()+"]");
|
||||||
|
}else{
|
||||||
|
iJsonSize = iJsonSize -1;
|
||||||
|
logger.info("Que["+(queIdx + 1)+"] service count :" + jsonData.size() + "/" + qTotalSize + "/" + "[Max-Tm:"+jsonData.get(iJsonSize).getRecptn_dt() +", Min-Tm:"+ jsonData.get(0).getRecptn_dt() + ", 분석중:"+packetQ.size()+"]");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
String sRetJsonData = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
sRetJsonData = mapper.writeValueAsString(asdeServiceVO);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
logger.error("[AsdeServiceController] makeServiceData-JsonProcessingException : " + CmmnUtil.getStatckTrace(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sRetJsonData;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String makeServiceDataFilter(int queIdx, Queue<ServiceAsdeData> procQue, String... filter){
|
||||||
|
|
||||||
|
String sendCode, sendMsg ;
|
||||||
|
SacpServiceHeader jsonHeader = new SacpServiceHeader();
|
||||||
|
List<ServiceAsdeData> jsonData = new LinkedList<ServiceAsdeData>();
|
||||||
|
|
||||||
|
sendCode = "200";
|
||||||
|
sendMsg = "";
|
||||||
|
|
||||||
|
asdeServiceVO = new SacpServiceVO();
|
||||||
|
|
||||||
|
int qTotalSize = procQue.size();
|
||||||
|
int qSize = qTotalSize;
|
||||||
|
|
||||||
|
if(qSize > scvDatacount) qSize = scvDatacount;
|
||||||
|
|
||||||
|
if(queIdx > scvQcount -1 || queIdx < 0) {
|
||||||
|
sendCode = "Err-01";
|
||||||
|
sendMsg = "할당되지 않은 큐를 지정했습니다.";
|
||||||
|
logger.error(sendMsg);
|
||||||
|
}else {
|
||||||
|
//if(procQue.peek() == null) {
|
||||||
|
if(qSize <= 0) {
|
||||||
|
sendCode = "200";
|
||||||
|
sendMsg = "전송할 데이터 없음.";
|
||||||
|
// logger.error("procQue size" + " / " + procQue.size());
|
||||||
|
}else{
|
||||||
|
|
||||||
|
serviceRunnig = true;
|
||||||
|
boolean bFilter = false;
|
||||||
|
|
||||||
|
while (qSize > 0 ) {
|
||||||
|
|
||||||
|
ServiceAsdeData data = procQue.poll();
|
||||||
|
|
||||||
|
if( data != null){
|
||||||
|
|
||||||
|
if(filter[0].equals(data.getClsgn())){
|
||||||
|
bFilter = true;
|
||||||
|
}else{bFilter = false;}
|
||||||
|
|
||||||
|
if(bFilter)
|
||||||
|
jsonData.add(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
qSize--;
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceRunnig = false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonHeader.setResult_code(sendCode);
|
||||||
|
jsonHeader.setResult_msg(sendMsg);
|
||||||
|
|
||||||
|
asdeServiceVO.setHeader(jsonHeader);
|
||||||
|
|
||||||
|
if (sendCode.equals("200")) {
|
||||||
|
|
||||||
|
asdeServiceVO.setData(jsonData);
|
||||||
|
|
||||||
|
int iJsonSize = jsonData.size();
|
||||||
|
if(iJsonSize <= 0 ){
|
||||||
|
iJsonSize = 0;
|
||||||
|
logger.info("Que["+(queIdx + 1)+"] service count :" + iJsonSize + "/" + qTotalSize + "/" + "[분석중:"+packetQ.size()+"]");
|
||||||
|
}else{
|
||||||
|
iJsonSize = iJsonSize -1;
|
||||||
|
logger.info("Que["+(queIdx + 1)+"] service count :" + iJsonSize + "/" + qTotalSize + "/" + "[Max-Tm:"+jsonData.get(iJsonSize).getRecptn_dt() +", Min-Tm:"+ jsonData.get(0).getRecptn_dt() + ", 분석중:"+packetQ.size()+"]");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
String sRetJsonData = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
sRetJsonData = mapper.writeValueAsString(asdeServiceVO);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
logger.error("[AsdeServiceController] makeServiceData-JsonProcessingException : " + CmmnUtil.getStatckTrace(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sRetJsonData;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
package kr.gmtc.gw.asderecv.rest;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Queue;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import kr.gmtc.gw.asderecv.rest.vo.ServiceAsdeData;
|
||||||
|
import kr.gmtc.gw.asderecv.utils.CmmnUtil;
|
||||||
|
import kr.gmtc.gw.comp.thread.CustomThread;
|
||||||
|
|
||||||
|
|
||||||
|
//@Component("serviceQueManager")
|
||||||
|
public class ServiceQueManager {
|
||||||
|
|
||||||
|
HashMap<Integer, Queue<ServiceAsdeData>> serviceQueue;
|
||||||
|
|
||||||
|
private boolean serviceRunnig = false;
|
||||||
|
private Integer scvQcount;
|
||||||
|
private Integer scvQmaxCount;
|
||||||
|
private Integer scvQdiffTime;
|
||||||
|
private Integer scvQclearTime;
|
||||||
|
|
||||||
|
private CustomThread serviceQClearThread;
|
||||||
|
|
||||||
|
protected Logger logger;
|
||||||
|
|
||||||
|
|
||||||
|
public ServiceQueManager(HashMap<Integer, Queue<ServiceAsdeData>> serviceQueue, boolean serviceRunnig){
|
||||||
|
|
||||||
|
this.serviceQueue = serviceQueue;
|
||||||
|
this.serviceRunnig = serviceRunnig;
|
||||||
|
|
||||||
|
logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
// 업무 스레드 생성, 대기 없이 무한반복
|
||||||
|
serviceQClearThread = new CustomThread("serviceQClearThread", this, CustomThread.NO_SLEEP, this::serviceQClear, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start(){
|
||||||
|
|
||||||
|
// 전송용 Queue 생성
|
||||||
|
createQueue();
|
||||||
|
|
||||||
|
serviceQClearThread.start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 설정에따라 REST용 서비스 큐 생성
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void createQueue() {
|
||||||
|
|
||||||
|
// String className = "java.util.Queue";
|
||||||
|
//Class cls = Class.forName(className);
|
||||||
|
|
||||||
|
for(int idx=0; idx<scvQcount; idx++) {
|
||||||
|
|
||||||
|
Queue<ServiceAsdeData> obj = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
obj = (Queue<ServiceAsdeData>) java.util.LinkedList.class.newInstance();
|
||||||
|
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
logger.error("[ServiceQueManager] createQueue-InstantiationException : " + CmmnUtil.getStatckTrace(e));
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
logger.error("[ServiceQueManager] createQueue-IllegalAccessException : " + CmmnUtil.getStatckTrace(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceQueue.put(idx, obj);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void serviceQClear() throws InterruptedException, IOException {
|
||||||
|
|
||||||
|
String sRecvTime = "";
|
||||||
|
|
||||||
|
ServiceAsdeData jsonData = new ServiceAsdeData();
|
||||||
|
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
|
||||||
|
|
||||||
|
LocalDateTime dateTime;
|
||||||
|
|
||||||
|
int iQcnt = 0;
|
||||||
|
|
||||||
|
if(serviceRunnig) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
for(int idx=0; idx<scvQcount; idx++) {
|
||||||
|
|
||||||
|
iQcnt = serviceQueue.get(idx).size();
|
||||||
|
|
||||||
|
if (iQcnt > scvQmaxCount ) {
|
||||||
|
|
||||||
|
jsonData = serviceQueue.get(idx).peek();
|
||||||
|
|
||||||
|
try {
|
||||||
|
sRecvTime = jsonData.getRecptn_dt();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 비정상 큐 Clear
|
||||||
|
serviceQueue.get(idx).clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
dateTime = LocalDateTime.parse(sRecvTime, formatter);
|
||||||
|
|
||||||
|
Duration diff = Duration.between(dateTime, LocalDateTime.now());
|
||||||
|
|
||||||
|
if( scvQclearTime > 0 && diff.toMillis() > scvQclearTime) { // 일정시간 미사용으로 판단
|
||||||
|
serviceQueue.get(idx).clear();
|
||||||
|
logger.info("[MainController] serviceQClear : " + (idx +1) +"번 Queue 장기 미사용으로 초기화 (" + iQcnt +"건), 설정시간:" + scvQclearTime);
|
||||||
|
}
|
||||||
|
else if( diff.toMillis() > scvQdiffTime) { // 데이터 과적재
|
||||||
|
|
||||||
|
iQcnt = serviceQueue.get(idx).size();
|
||||||
|
int iPollCnt = iQcnt - scvQmaxCount;
|
||||||
|
|
||||||
|
while (iQcnt - scvQmaxCount >= 0) {
|
||||||
|
serviceQueue.get(idx).poll();
|
||||||
|
iQcnt--;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("[MainController] serviceQpoll : " + (idx +1) +"번 Queue 일부 버림 (" + iPollCnt +"건), 설정시간:" + scvQdiffTime + " 설정건수:"+ scvQmaxCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.error("[MainController] serviceQClear-InterruptedException : " + CmmnUtil.getStatckTrace(e));
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("[MainController] serviceQClear-Exception : " + CmmnUtil.getStatckTrace(e) + ">> " + sRecvTime.toString() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScvQcount(Integer scvQcount) {
|
||||||
|
this.scvQcount = scvQcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScvQmaxCount(Integer scvQmaxCount) {
|
||||||
|
this.scvQmaxCount = scvQmaxCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScvQdiffTime(Integer scvQdiffTime) {
|
||||||
|
this.scvQdiffTime = scvQdiffTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScvQclearTime(Integer scvQclearTime) {
|
||||||
|
this.scvQclearTime = scvQclearTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package kr.gmtc.gw.asderecv.rest.vo;
|
||||||
|
|
||||||
|
public class SacpServiceHeader {
|
||||||
|
|
||||||
|
private String result_code; // 결과코드
|
||||||
|
private String result_msg; // 결과메시지
|
||||||
|
|
||||||
|
public String getResult_code() {
|
||||||
|
return result_code;
|
||||||
|
}
|
||||||
|
public void setResult_code(String result_code) {
|
||||||
|
this.result_code = result_code;
|
||||||
|
}
|
||||||
|
public String getResult_msg() {
|
||||||
|
return result_msg;
|
||||||
|
}
|
||||||
|
public void setResult_msg(String result_msg) {
|
||||||
|
this.result_msg = result_msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package kr.gmtc.gw.asderecv.rest.vo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SacpServiceVO {
|
||||||
|
|
||||||
|
private SacpServiceHeader header;
|
||||||
|
private List<ServiceAsdeData> data;
|
||||||
|
|
||||||
|
public SacpServiceHeader getHeader() {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
public void setHeader(SacpServiceHeader header) {
|
||||||
|
this.header = header;
|
||||||
|
}
|
||||||
|
public List<ServiceAsdeData> getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
public void setData(List<ServiceAsdeData> data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package kr.gmtc.gw.asderecv.rest.vo;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ServiceAsdeData {
|
||||||
|
|
||||||
|
private String cat_ty; // 카테고리 유형 (10:Cat10, 11:Cat11)
|
||||||
|
private String clsgn; // Callsign
|
||||||
|
private String tail_no; // 항공기등록기호
|
||||||
|
private String mode_s_cd; // Mode-S 코드
|
||||||
|
private String ssr_cd; // SSR 코드(squawkcode)
|
||||||
|
|
||||||
|
private String track_no; // Track number
|
||||||
|
private String trgt_id; // 타겟 ID
|
||||||
|
private String recptn_dt; // 수신일시
|
||||||
|
|
||||||
|
// private String posx; //x좌표
|
||||||
|
// private String posy; // y 좌표
|
||||||
|
|
||||||
|
private String lat; // 위도
|
||||||
|
private String lon; // 경도
|
||||||
|
private String spd; // 속도
|
||||||
|
private String cos; // 방위
|
||||||
|
private String trgt_ty; // 타겟 ID
|
||||||
|
|
||||||
|
private String alt; // 고도
|
||||||
|
// private String carty; // 조업차량 분류
|
||||||
|
|
||||||
|
|
||||||
|
public ServiceAsdeData() {
|
||||||
|
super();
|
||||||
|
this.cat_ty = "";
|
||||||
|
this.trgt_id = "";
|
||||||
|
this.mode_s_cd = "";
|
||||||
|
this.ssr_cd = "";
|
||||||
|
this.clsgn = "";
|
||||||
|
this.tail_no = "";
|
||||||
|
this.track_no = "";
|
||||||
|
this.recptn_dt = "";
|
||||||
|
// this.posx = "0";
|
||||||
|
// this.posy = "0";
|
||||||
|
this.lat = "0";
|
||||||
|
this.lon = "0";
|
||||||
|
this.spd = "0";
|
||||||
|
this.cos = "0";
|
||||||
|
this.trgt_ty = "0";
|
||||||
|
this.alt = "0";
|
||||||
|
// this.carty = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "trgt_id=" + trgt_id + ", mode_s_cd=" + mode_s_cd + ", ssr_cd=" + ssr_cd + ", clsgn="
|
||||||
|
+ clsgn + ", tail_no=" + tail_no + ", track_no=" + track_no + ", recptn_dt=" + recptn_dt + ", cat_ty="
|
||||||
|
+ cat_ty + ", lat=" + lat + ", lon=" + lon + ", spd=" + spd + ", cos=" + cos + ", trgt_type=" + trgt_ty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package kr.gmtc.gw.asderecv.utils;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
public class CmmnUtil {
|
||||||
|
public static String getStatckTrace(Throwable t) {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
t.printStackTrace(new PrintWriter(sw));
|
||||||
|
return sw.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package kr.gmtc.gw.comp.socket.event;
|
||||||
|
|
||||||
|
public abstract class EncryptEventListener implements IEncryptEventListener {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package kr.gmtc.gw.comp.socket.event;
|
||||||
|
|
||||||
|
public interface IEncryptEventListener {
|
||||||
|
public byte[] getByteArray(int id, byte[] data);
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package kr.gmtc.gw.comp.socket.type;
|
||||||
|
|
||||||
|
public enum ActiveModeType {
|
||||||
|
PRIMARY("PRIMARY"),
|
||||||
|
SECONDARY("SECONDARY");
|
||||||
|
|
||||||
|
private final String typeName;
|
||||||
|
|
||||||
|
private ActiveModeType(String name) {
|
||||||
|
this.typeName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.typeName;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package kr.gmtc.gw.comp.socket.type;
|
||||||
|
|
||||||
|
public enum NetStatType {
|
||||||
|
NONE("NONE"),
|
||||||
|
SEND_OK("SEND_OK"),
|
||||||
|
ERROR("ERROR"),
|
||||||
|
WOULDBLOCK("WOULD_BLOCK"),
|
||||||
|
DISCONNECT("DISCONNECT");
|
||||||
|
|
||||||
|
private final String typeName;
|
||||||
|
|
||||||
|
private NetStatType(String name) {
|
||||||
|
this.typeName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getname() {
|
||||||
|
return this.typeName;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package kr.gmtc.gw.comp.socket.udp;
|
||||||
|
|
||||||
|
import kr.gmtc.gw.comp.socket.vo.MsgObjVO;
|
||||||
|
|
||||||
|
public interface IUDPSocketHandler {
|
||||||
|
public void udpDataIn(MsgObjVO vo);
|
||||||
|
public void udpSendData(MsgObjVO vo);
|
||||||
|
public void udpSendData(String ip, int port, MsgObjVO vo);
|
||||||
|
|
||||||
|
public void connected(String ip, int port, int statusCode, String description);
|
||||||
|
public void disconnected(String ip, int port, int statusCode, String description);
|
||||||
|
public void connectionStatus(String ip, int port, String connEvent, int statusCode, String description);
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package kr.gmtc.gw.comp.socket.udp;
|
||||||
|
|
||||||
|
public abstract class UDPEventListener implements IUDPSocketHandler {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,342 @@
|
||||||
|
package kr.gmtc.gw.comp.socket.udp;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
import kr.gmtc.gw.comp.socket.event.EncryptEventListener;
|
||||||
|
import kr.gmtc.gw.comp.socket.type.ActiveModeType;
|
||||||
|
import kr.gmtc.gw.comp.socket.utils.SocketUtil;
|
||||||
|
import kr.gmtc.gw.comp.socket.vo.MsgObjVO;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import java.io.File;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class UDPManager {
|
||||||
|
private String path;
|
||||||
|
private Logger logger;
|
||||||
|
|
||||||
|
private Thread checkSocketThread;
|
||||||
|
|
||||||
|
private HashMap<Integer, UDPSocket> udpSockets;
|
||||||
|
private UDPEventListener listener;
|
||||||
|
private boolean isRunning;
|
||||||
|
|
||||||
|
private EncryptEventListener encryptListener;
|
||||||
|
private EncryptEventListener decryptListener;
|
||||||
|
|
||||||
|
|
||||||
|
public UDPManager(String path, UDPEventListener listener) {
|
||||||
|
|
||||||
|
this.path = path;
|
||||||
|
this.listener = listener;
|
||||||
|
|
||||||
|
this.logger = LoggerFactory.getLogger(UDPManager.class);
|
||||||
|
|
||||||
|
this.isRunning = true;
|
||||||
|
|
||||||
|
udpSockets = new HashMap<Integer, UDPSocket>();
|
||||||
|
|
||||||
|
checkSocketThread = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while(isRunning) {
|
||||||
|
try {
|
||||||
|
checkReconnect();
|
||||||
|
Thread.sleep(10000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.error(SocketUtil.getStatckTrace(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
checkSocketThread.setName("UDPManager-checkSocketThread");
|
||||||
|
|
||||||
|
initializeUDPFromXML();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
isRunning = true;
|
||||||
|
logger.info("====================== SYSTEM Start ======================");
|
||||||
|
|
||||||
|
startClient();
|
||||||
|
// recvQThread.start();
|
||||||
|
// sendQThread.start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
isRunning = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void initializeUDPFromXML() {
|
||||||
|
if (path.equals("")) {
|
||||||
|
path = System.getProperty("user.dir");
|
||||||
|
}
|
||||||
|
|
||||||
|
File xmlFile = new File(path+"/cfg/udpsocket.xml");
|
||||||
|
|
||||||
|
if (!xmlFile.exists()) {
|
||||||
|
logger.error("[UDPManager] Load fail .. : "+ path+"\\cfg\\udpsocket.xml");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("[UDPManager] Load file .. : "+ path+"\\cfg\\udpsocket.xml");
|
||||||
|
|
||||||
|
try {
|
||||||
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||||
|
Document doc = builder.parse(xmlFile);
|
||||||
|
|
||||||
|
NodeList nodes = doc.getElementsByTagName("UdpSocket");
|
||||||
|
|
||||||
|
for(int i = 0; i < nodes.getLength(); i++ ) {
|
||||||
|
Node udpSocketNode = nodes.item(i);
|
||||||
|
|
||||||
|
|
||||||
|
int id = -1;
|
||||||
|
boolean use = false;
|
||||||
|
String primaryIP = "";
|
||||||
|
String secondaryIP = "";
|
||||||
|
int port = 0;
|
||||||
|
String name = "";
|
||||||
|
boolean lineMode = true;
|
||||||
|
boolean reconnUse = true;
|
||||||
|
int reconnInterval = 60;
|
||||||
|
String inout = "";
|
||||||
|
String mcastgroup = "";
|
||||||
|
|
||||||
|
for(Node child = udpSocketNode.getFirstChild(); child != null; child = child.getNextSibling()) {
|
||||||
|
if (child.getNodeType() != Node.ELEMENT_NODE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Element childElement = (Element) child;
|
||||||
|
|
||||||
|
if(childElement.getNodeName().equals("Connection")) {
|
||||||
|
id = SocketUtil.strToIntDef(childElement.getAttribute("ID"), -1);
|
||||||
|
// tag = SocketUtil.strToIntDef(childElement.getAttribute("TAG"), -1);
|
||||||
|
primaryIP = childElement.getAttribute("PIP");
|
||||||
|
secondaryIP = childElement.getAttribute("SIP");
|
||||||
|
port = SocketUtil.strToIntDef(childElement.getAttribute("PORT"), 0);
|
||||||
|
use = Boolean.parseBoolean(childElement.getAttribute("USE"));
|
||||||
|
name = childElement.getAttribute("Name");
|
||||||
|
}
|
||||||
|
else if(child.getNodeName().equals("Option")) {
|
||||||
|
lineMode = Boolean.parseBoolean(childElement.getAttribute("LineMode"));
|
||||||
|
inout = childElement.getAttribute("InOut");
|
||||||
|
mcastgroup = childElement.getAttribute("McastGrp");
|
||||||
|
}
|
||||||
|
else if(child.getNodeName().equals("Reconnect")) {
|
||||||
|
reconnUse = Boolean.parseBoolean(childElement.getAttribute("ReconnUSE"));
|
||||||
|
reconnInterval = SocketUtil.strToIntDef(childElement.getAttribute("Interval"), 60);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(SocketUtil.getStatckTrace(e));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!use || primaryIP.equals("") || port == 0 || id == -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
UDPSocket udpSocket = new UDPSocket();
|
||||||
|
udpSocket.setId(id);
|
||||||
|
udpSocket.setName(name);
|
||||||
|
udpSocket.setPrimaryIP(primaryIP);
|
||||||
|
udpSocket.setSecodaryIP(secondaryIP);
|
||||||
|
udpSocket.setPort(port);
|
||||||
|
udpSocket.setUse(use);
|
||||||
|
udpSocket.setLineMode(lineMode);
|
||||||
|
udpSocket.setInOut(inout);
|
||||||
|
udpSocket.setMultiCastGroup(mcastgroup);
|
||||||
|
udpSocket.setReconnUse(reconnUse);
|
||||||
|
udpSocket.setInterval(reconnInterval);
|
||||||
|
udpSocket.setEventListener(listener);
|
||||||
|
udpSocket.setEncryptListener(encryptListener);
|
||||||
|
udpSocket.setDecryptListener(decryptListener);
|
||||||
|
|
||||||
|
if (!udpSockets.containsKey(udpSocket.getId())) {
|
||||||
|
|
||||||
|
String msg = "[UDP Socket] ID : "+ String.valueOf(udpSocket.getId()) +" IP : "+ udpSocket.getPrimaryIP() +" PORT : "+ String.valueOf(udpSocket.getPort());
|
||||||
|
logger.info(msg);
|
||||||
|
|
||||||
|
udpSockets.put(udpSocket.getId(), udpSocket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(SocketUtil.getStatckTrace(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startClient() {
|
||||||
|
for (UDPSocket udpSocket : udpSockets.values()) {
|
||||||
|
if (udpSocket == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!udpSocket.isUse()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isActive = udpSocket.activeSocket(udpSocket.getPrimaryIP(), udpSocket.getPort());
|
||||||
|
String msg = "";
|
||||||
|
if (isActive == 0) {
|
||||||
|
msg = "[UDP Manager][CONNECTED - " + udpSocket.getActiveModeName() + "]["+ udpSocket.getPrimaryIP() +"]["+ String.valueOf(udpSocket.getPort()) +"] ";
|
||||||
|
} else {
|
||||||
|
msg = "[UDP Manager][ERROR- " + udpSocket.getActiveModeName() + "]["+ udpSocket.getPrimaryIP() +"]["+ String.valueOf(udpSocket.getPort()) +"] ";
|
||||||
|
}
|
||||||
|
logger.info(msg);
|
||||||
|
}
|
||||||
|
if (checkSocketThread != null) {
|
||||||
|
checkSocketThread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void checkReconnect() {
|
||||||
|
for(UDPSocket udpSocket : udpSockets.values()) {
|
||||||
|
if (udpSocket == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isReconn = false;
|
||||||
|
LocalDateTime lastRecvDT = udpSocket.getRecvdt();
|
||||||
|
Duration duration = Duration.between(lastRecvDT, LocalDateTime.now());
|
||||||
|
|
||||||
|
String logMsg = "";
|
||||||
|
if (!udpSocket.isActive()) {
|
||||||
|
isReconn = true;
|
||||||
|
} else if(udpSocket.isReconnUse() && duration.getSeconds() >= udpSocket.getInterval()) {
|
||||||
|
isReconn = true;
|
||||||
|
logMsg = "[UDP Manager] Messages are not received for "+ String.valueOf(udpSocket.getInterval()) +" seconds";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isReconn) {
|
||||||
|
// String logMsg = "";
|
||||||
|
|
||||||
|
ActiveModeType activeSocket = udpSocket.getActiveModeType();
|
||||||
|
String sActiveName = udpSocket.getActiveModeName();
|
||||||
|
|
||||||
|
if (activeSocket == ActiveModeType.PRIMARY) {
|
||||||
|
logMsg = "[UDP Manager]["+ sActiveName +"-"+ udpSocket.getSecodaryIP() +":"+ String.valueOf(udpSocket.getPort()) +"(P -> S)] "+udpSocket.getName() +" Change connected.."+ logMsg;
|
||||||
|
} else {
|
||||||
|
logMsg = "[UDP Manager]["+ sActiveName +"-"+ udpSocket.getPrimaryIP() +":"+ String.valueOf(udpSocket.getPort()) +"(S -> P)] "+udpSocket.getName() +" Change connected.."+ logMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(logMsg);
|
||||||
|
|
||||||
|
int isActive = udpSocket.changeActive();
|
||||||
|
|
||||||
|
if (isActive == 0) {
|
||||||
|
udpSocket.setRecvdt(LocalDateTime.now());
|
||||||
|
|
||||||
|
logMsg = "["+ udpSocket.getCurrentIP() +":"+ String.valueOf(udpSocket.getPort()) +
|
||||||
|
"("+ String.valueOf(udpSocket.getActiveModeType()) +")] "+
|
||||||
|
udpSocket.getName() +" Connected.. ";
|
||||||
|
} else {
|
||||||
|
logMsg = "["+ udpSocket.getCurrentIP() +":"+ String.valueOf(udpSocket.getPort()) +
|
||||||
|
"("+ String.valueOf(udpSocket.getActiveModeType()) +")] "+
|
||||||
|
udpSocket.getName() +" Connect fail.. ";
|
||||||
|
}
|
||||||
|
logger.info(logMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean disconnect(int id) {
|
||||||
|
boolean result = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
UDPSocket udpSocket = this.udpSockets.get(id);
|
||||||
|
if (udpSocket != null) {
|
||||||
|
result = udpSocket.inActive();
|
||||||
|
}
|
||||||
|
} catch(Exception e) {
|
||||||
|
logger.error("[GmtUDPManager] udp socket deactive fail : "+ SocketUtil.getStatckTrace(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean disconnect(String ip, int port) {
|
||||||
|
boolean result = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
for(UDPSocket udpSocket : this.udpSockets.values()) {
|
||||||
|
if( (ip.equals(udpSocket.getPrimaryIP()) || ip.equals(udpSocket.getSecodaryIP())) && udpSocket.getPort() == port ) {
|
||||||
|
result = udpSocket.inActive();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(Exception e) {
|
||||||
|
logger.error("[GmtUDPManager] udp socket deactive fail : "+ SocketUtil.getStatckTrace(e) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// private void recvDataIn(MsgObjVO vo) {
|
||||||
|
// try {
|
||||||
|
// // udpDataIn(vo);
|
||||||
|
|
||||||
|
// // if (udpListener != null) {
|
||||||
|
// // udpListener.udpDataIn(vo);
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// logger.error(SocketUtil.getStatckTrace(e));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void broadcastMsg(MsgObjVO vo) {
|
||||||
|
for (UDPSocket udpSocket : udpSockets.values()) {
|
||||||
|
if (udpSocket.equalsIP(vo.getRecvIP()) && udpSocket.getPort() == vo.getRecvPort()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MsgObjVO newVO = vo.getClone();
|
||||||
|
|
||||||
|
udpSocket.addSendMsg(newVO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMsg(String clientIP, int clientPort, MsgObjVO vo) {
|
||||||
|
for (UDPSocket udpSocket : udpSockets.values()) {
|
||||||
|
if (udpSocket.equalsIP(vo.getRecvIP()) && udpSocket.getPort() == vo.getRecvPort()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (udpSocket.equalsIP(clientIP) && udpSocket.getPort() == clientPort) {
|
||||||
|
MsgObjVO newVO = vo.getClone();
|
||||||
|
|
||||||
|
udpSocket.addSendMsg(newVO);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setEncryptListener(EncryptEventListener encryptListener) {
|
||||||
|
this.encryptListener = encryptListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDecryptListener(EncryptEventListener decryptListener) {
|
||||||
|
this.decryptListener = decryptListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,522 @@
|
||||||
|
package kr.gmtc.gw.comp.socket.udp;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import ipworks.IPWorksException;
|
||||||
|
import ipworks.Mcast;
|
||||||
|
import ipworks.McastDataInEvent;
|
||||||
|
import ipworks.McastErrorEvent;
|
||||||
|
import ipworks.McastEventListener;
|
||||||
|
import ipworks.McastReadyToSendEvent;
|
||||||
|
import kr.gmtc.gw.comp.socket.event.EncryptEventListener;
|
||||||
|
import kr.gmtc.gw.comp.socket.type.ActiveModeType;
|
||||||
|
import kr.gmtc.gw.comp.socket.type.NetStatType;
|
||||||
|
import kr.gmtc.gw.comp.socket.utils.SocketUtil;
|
||||||
|
import kr.gmtc.gw.comp.socket.vo.MsgObjVO;
|
||||||
|
import kr.gmtc.gw.comp.socket.vo.NetStatVO;
|
||||||
|
|
||||||
|
public class UDPSocket {
|
||||||
|
|
||||||
|
protected Logger logger;
|
||||||
|
|
||||||
|
private final Mcast udpport;
|
||||||
|
private final Thread sendThread;
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private int tag;
|
||||||
|
private String name;
|
||||||
|
private String primaryIP;
|
||||||
|
private String secodaryIP;
|
||||||
|
private int port;
|
||||||
|
private ActiveModeType activeModeType;
|
||||||
|
private boolean lineMode;
|
||||||
|
private String inOut;
|
||||||
|
private String multiCastGroup;
|
||||||
|
private LocalDateTime recvdt;
|
||||||
|
private LocalDateTime senddt;
|
||||||
|
private boolean use;
|
||||||
|
private boolean reconnUse;
|
||||||
|
private int interval;
|
||||||
|
private boolean doResend;
|
||||||
|
private boolean isRunning;
|
||||||
|
|
||||||
|
private MsgObjVO reSendVO;
|
||||||
|
private NetStatVO netStatVO;
|
||||||
|
|
||||||
|
//private final Queue<MsgObjVO> recvQ;
|
||||||
|
private final Queue<MsgObjVO> sendQ;
|
||||||
|
|
||||||
|
private EncryptEventListener encryptListener;
|
||||||
|
private EncryptEventListener decryptListener;
|
||||||
|
private UDPEventListener eventListener;
|
||||||
|
|
||||||
|
//public UDPSocket(Queue<MsgObjVO> recvQ){
|
||||||
|
public UDPSocket(){
|
||||||
|
|
||||||
|
logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
netStatVO = new NetStatVO();
|
||||||
|
|
||||||
|
udpport = new Mcast();
|
||||||
|
|
||||||
|
id = -1;
|
||||||
|
name = "";
|
||||||
|
primaryIP = "";
|
||||||
|
secodaryIP = "";
|
||||||
|
activeModeType = ActiveModeType.PRIMARY;
|
||||||
|
lineMode = true;
|
||||||
|
multiCastGroup = "";
|
||||||
|
recvdt = LocalDateTime.now();
|
||||||
|
senddt = LocalDateTime.now();
|
||||||
|
isRunning = true;
|
||||||
|
reconnUse = true;
|
||||||
|
use = true;
|
||||||
|
interval = 0;
|
||||||
|
inOut = "RECV";
|
||||||
|
//this.recvQ = recvQ;
|
||||||
|
|
||||||
|
sendQ = new LinkedBlockingQueue<MsgObjVO>(100000);
|
||||||
|
|
||||||
|
try {
|
||||||
|
udpport.setRuntimeLicense("31504A42564131535542524131535542414E44323132323200000000000000000000000000000000505A4E384E5758350000325242435038313258424E480000");
|
||||||
|
|
||||||
|
udpport.addMcastEventListener(new McastEventListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dataIn(McastDataInEvent e) {
|
||||||
|
processRcvData(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(McastErrorEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readyToSend(McastReadyToSendEvent e) {}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("[UDP Socket] EventListener error : " + ex.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
sendThread = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while(isRunning) {
|
||||||
|
try {
|
||||||
|
udpSendMsgQue();
|
||||||
|
Thread.sleep(1);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sendThread.setName("UDP-Socket-sendThread");
|
||||||
|
sendThread.start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int activeSocket(String ip, int port){
|
||||||
|
if(udpport == null){
|
||||||
|
logger.error("[UDP Socket] declare");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
udpport.setActive(false);
|
||||||
|
|
||||||
|
if(inOut.equals("SEND")) {
|
||||||
|
|
||||||
|
udpport.setRemoteHost(ip);
|
||||||
|
udpport.setRemotePort(port);
|
||||||
|
udpport.setActive(true);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
udpport.setLocalPort(port);
|
||||||
|
udpport.setActive(true);
|
||||||
|
|
||||||
|
if( !(multiCastGroup == null || multiCastGroup.equals("")) )
|
||||||
|
udpport.setMulticastGroup(multiCastGroup);
|
||||||
|
|
||||||
|
logger.info("[UDP Socket] MultiCalstGroup : " + multiCastGroup + " port:" + port);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("[UDP Socket] " + inOut + " : " + ip + ":" + port);
|
||||||
|
|
||||||
|
}catch (IPWorksException e){
|
||||||
|
logger.error("[UDP Socket] active fail : " + e.getMessage() );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean inActive(){
|
||||||
|
|
||||||
|
try{
|
||||||
|
udpport.setActive(false);
|
||||||
|
} catch(IPWorksException e) {
|
||||||
|
logger.error("[UDP Socket] inActive fail : " + e.getMessage() );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int changeActive(){
|
||||||
|
if(udpport == null){
|
||||||
|
logger.error("UDP socket declare");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
String ip = "" ;
|
||||||
|
|
||||||
|
switch (activeModeType) {
|
||||||
|
case PRIMARY:
|
||||||
|
ip = this.secodaryIP;
|
||||||
|
activeModeType = ActiveModeType.SECONDARY;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SECONDARY:
|
||||||
|
ip = this.primaryIP;
|
||||||
|
activeModeType = ActiveModeType.PRIMARY;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int iActive = activeSocket(ip, port);
|
||||||
|
|
||||||
|
return iActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processRcvData(McastDataInEvent data) {
|
||||||
|
try {
|
||||||
|
recvdt = LocalDateTime.now();
|
||||||
|
|
||||||
|
MsgObjVO vo = new MsgObjVO();
|
||||||
|
|
||||||
|
vo.setMsgSeq(0);
|
||||||
|
vo.setRecvIP(udpport.getRemoteHost());
|
||||||
|
vo.setRecvPort(udpport.getRemotePort());
|
||||||
|
vo.setRecvID(id);
|
||||||
|
vo.setRecvTag(tag);
|
||||||
|
vo.setRecvDT(LocalDateTime.now());
|
||||||
|
vo.setRecvServerPort(port);
|
||||||
|
vo.setMsg(data.datagram);
|
||||||
|
|
||||||
|
recvdt = LocalDateTime.now();
|
||||||
|
|
||||||
|
if (decryptListener != null) {
|
||||||
|
vo.setMsg(decryptListener.getByteArray(this.id, vo.getMsg()));
|
||||||
|
}
|
||||||
|
//recvQ.offer(vo);
|
||||||
|
if (eventListener != null) {
|
||||||
|
eventListener.udpDataIn(vo);
|
||||||
|
}
|
||||||
|
|
||||||
|
vo = null;
|
||||||
|
|
||||||
|
} catch(Exception e) {
|
||||||
|
logger.error(SocketUtil.getStatckTrace(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int udpSendMsgQue(){
|
||||||
|
|
||||||
|
int resultCode = -1;
|
||||||
|
|
||||||
|
if (!udpport.isActive()) {
|
||||||
|
sendQ.clear();
|
||||||
|
netStatVO.setStat(NetStatType.DISCONNECT);
|
||||||
|
return resultCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sendQ == null) return -1;
|
||||||
|
|
||||||
|
int cnt = sendQ.size();
|
||||||
|
if(cnt > 1000){
|
||||||
|
cnt = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i <= cnt-1; i++) {
|
||||||
|
try{
|
||||||
|
if( netStatVO.getStat() == NetStatType.NONE || netStatVO.getStat() == NetStatType.SEND_OK || !doResend){
|
||||||
|
MsgObjVO vo = sendQ.poll();
|
||||||
|
if (vo != null) {
|
||||||
|
resultCode = sendMsg(vo);
|
||||||
|
processSendResult(resultCode, vo, false);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if (reSendVO == null) {
|
||||||
|
netStatVO.setStat(NetStatType.NONE);
|
||||||
|
resultCode = 0;
|
||||||
|
}
|
||||||
|
resultCode = sendMsg(reSendVO);
|
||||||
|
processSendResult(resultCode, reSendVO, true);
|
||||||
|
}
|
||||||
|
}catch (Exception e) {
|
||||||
|
logger.error("[UDP Socket] udpSendMsgQue error " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int sendMsg(MsgObjVO vo) {
|
||||||
|
int resultCode = -1;
|
||||||
|
if (udpport.isActive()) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (encryptListener != null) {
|
||||||
|
vo.setMsg(encryptListener.getByteArray(this.id, vo.getMsg()));
|
||||||
|
}
|
||||||
|
|
||||||
|
udpport.send(vo.getMsg());
|
||||||
|
|
||||||
|
if (lineMode) {
|
||||||
|
udpport.send("\r\n".getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
resultCode = 0;
|
||||||
|
|
||||||
|
} catch (IPWorksException e) {
|
||||||
|
resultCode = e.getCode();
|
||||||
|
|
||||||
|
logger.error("[UDP Socket]["+ udpport.getRemoteHost() +"]["+ String.valueOf(udpport.getRemotePort()) +"] (" + e.getCode() + ") " + e.getMessage() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processSendResult(int resultCode, MsgObjVO vo, boolean isReSend) {
|
||||||
|
try {
|
||||||
|
switch(resultCode) {
|
||||||
|
|
||||||
|
case SocketUtil.NET_SEND_OK :
|
||||||
|
netStatVO.setStat(NetStatType.SEND_OK);
|
||||||
|
netStatVO.setWouldBlockFromTime(SocketUtil.defaultTime());
|
||||||
|
netStatVO.setWouldBlockToTime(SocketUtil.defaultTime());
|
||||||
|
netStatVO.setDescription("");
|
||||||
|
netStatVO.setLastSendTime(LocalDateTime.now());
|
||||||
|
netStatVO.setRetryCount(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SocketUtil.NET_WOULD_BLOCK :
|
||||||
|
if (isReSend) {
|
||||||
|
reSendVO = null;
|
||||||
|
} else {
|
||||||
|
reSendVO = vo;
|
||||||
|
}
|
||||||
|
|
||||||
|
netStatVO.setStat(NetStatType.WOULDBLOCK);
|
||||||
|
if (netStatVO.getWouldBlockFromTime().isEqual(SocketUtil.defaultTime())) {
|
||||||
|
netStatVO.setWouldBlockFromTime(LocalDateTime.now());
|
||||||
|
}
|
||||||
|
netStatVO.setWouldBlockToTime(LocalDateTime.now());
|
||||||
|
netStatVO.setDescription("Operation Would Block");
|
||||||
|
if(netStatVO.getLastSendTime().isEqual(SocketUtil.defaultTime())){
|
||||||
|
netStatVO.setLastSendTime(LocalDateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.sleep(10);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
if (isReSend) {
|
||||||
|
reSendVO = null;
|
||||||
|
} else {
|
||||||
|
reSendVO = vo;
|
||||||
|
}
|
||||||
|
|
||||||
|
netStatVO.setStat(NetStatType.DISCONNECT);
|
||||||
|
netStatVO.setWouldBlockFromTime(SocketUtil.defaultTime());
|
||||||
|
netStatVO.setWouldBlockToTime(SocketUtil.defaultTime());
|
||||||
|
netStatVO.setDescription("Socket Error");
|
||||||
|
|
||||||
|
if (netStatVO.getRetryCount() == 0) {
|
||||||
|
netStatVO.setRetryCount(netStatVO.getRetryCount() +1);
|
||||||
|
netStatVO.setLastSendTime(LocalDateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.sleep(10);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch(Exception e) {
|
||||||
|
logger.error("[UDP Socket] Process send result error : " + SocketUtil.getStatckTrace(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public boolean isActive() {
|
||||||
|
return udpport.isActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrentIP() {
|
||||||
|
return udpport.getRemoteHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equalsIP(String ip) {
|
||||||
|
if (ip.equals(primaryIP) || ip.equals(secodaryIP)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSendMsg(MsgObjVO vo) {
|
||||||
|
if (vo != null && sendQ != null && udpport.isActive()) {
|
||||||
|
sendQ.offer(vo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getActiveModeName() {
|
||||||
|
return activeModeType.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////// Getter Setter ////////////////////////////
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTag(int tag) {
|
||||||
|
this.tag = tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrimaryIP() {
|
||||||
|
return primaryIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrimaryIP(String primaryIP) {
|
||||||
|
this.primaryIP = primaryIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSecodaryIP() {
|
||||||
|
return secodaryIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecodaryIP(String secodaryIP) {
|
||||||
|
this.secodaryIP = secodaryIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPort(int port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActiveModeType getActiveModeType() {
|
||||||
|
return activeModeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActiveModeType(ActiveModeType activeModeType) {
|
||||||
|
this.activeModeType = activeModeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLineMode() {
|
||||||
|
return lineMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLineMode(boolean lineMode) {
|
||||||
|
this.lineMode = lineMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInOut() {
|
||||||
|
return inOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInOut(String inOut) {
|
||||||
|
this.inOut = inOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMultiCastGroup() {
|
||||||
|
return multiCastGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMultiCastGroup(String multiCastGroup) {
|
||||||
|
this.multiCastGroup = multiCastGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getRecvdt() {
|
||||||
|
return recvdt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecvdt(LocalDateTime recvdt) {
|
||||||
|
this.recvdt = recvdt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getSenddt() {
|
||||||
|
return senddt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenddt(LocalDateTime senddt) {
|
||||||
|
this.senddt = senddt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUse() {
|
||||||
|
return use;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUse(boolean use) {
|
||||||
|
this.use = use;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReconnUse() {
|
||||||
|
return reconnUse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReconnUse(boolean reconnUse) {
|
||||||
|
this.reconnUse = reconnUse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInterval() {
|
||||||
|
return interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterval(int interval) {
|
||||||
|
this.interval = interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEncryptListener(EncryptEventListener encryptListener) {
|
||||||
|
this.encryptListener = encryptListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDecryptListener(EncryptEventListener decryptListener) {
|
||||||
|
this.decryptListener = decryptListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEventListener(UDPEventListener eventListener) {
|
||||||
|
this.eventListener = eventListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,722 @@
|
||||||
|
package kr.gmtc.gw.comp.socket.utils;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.net.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class SocketUtil {
|
||||||
|
public static final int NET_WOULD_BLOCK = 135;
|
||||||
|
public static final int NET_SEND_OK = 0;
|
||||||
|
|
||||||
|
public static int strToIntDef(String s, int def) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
int intVal = Integer.parseInt(s);
|
||||||
|
return intVal;
|
||||||
|
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LocalDateTime defaultTime() {
|
||||||
|
return LocalDateTime.of(1899, 12, 30, 00, 00);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getStatckTrace(Throwable t) {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
t.printStackTrace(new PrintWriter(sw));
|
||||||
|
return sw.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String GetAddress(String addressType) {
|
||||||
|
String address = "";
|
||||||
|
InetAddress lanIp = null;
|
||||||
|
try {
|
||||||
|
|
||||||
|
String ipAddress = null;
|
||||||
|
Enumeration<NetworkInterface> net = null;
|
||||||
|
net = NetworkInterface.getNetworkInterfaces();
|
||||||
|
|
||||||
|
while (net.hasMoreElements()) {
|
||||||
|
NetworkInterface element = net.nextElement();
|
||||||
|
Enumeration<InetAddress> addresses = element.getInetAddresses();
|
||||||
|
|
||||||
|
while (addresses.hasMoreElements()) {
|
||||||
|
InetAddress ip = addresses.nextElement();
|
||||||
|
if (ip instanceof Inet4Address) {
|
||||||
|
if (ip.isSiteLocalAddress()) {
|
||||||
|
ipAddress = ip.getHostAddress();
|
||||||
|
lanIp = InetAddress.getByName(ipAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lanIp == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (addressType.equals("ip")) {
|
||||||
|
address = lanIp.toString().replaceAll("^/+", "");
|
||||||
|
} else if (addressType.equals("mac")) {
|
||||||
|
address = getMacAddress(lanIp);
|
||||||
|
} else {
|
||||||
|
throw new Exception("Specify \"ip\" or \"mac\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (UnknownHostException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
} catch (SocketException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getMacAddress(InetAddress ip) {
|
||||||
|
String address = null;
|
||||||
|
try {
|
||||||
|
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
|
||||||
|
byte[] mac = network.getHardwareAddress();
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < mac.length; i++) {
|
||||||
|
sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
|
||||||
|
}
|
||||||
|
address = sb.toString();
|
||||||
|
} catch (SocketException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String makeCRC(String value) throws Exception {
|
||||||
|
return makeCRC(value, "EUC-KR");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String makeCRC(String value, String charset) throws Exception {
|
||||||
|
|
||||||
|
byte[] byteStr = value.getBytes(charset);
|
||||||
|
byte checkSum = 0;
|
||||||
|
|
||||||
|
for (int i = 1; i < byteStr.length; i++) {
|
||||||
|
checkSum = (byte) (checkSum ^ byteStr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
String result = String.format("%02X", checkSum);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean checkCRC(String value, String seperator) throws Exception {
|
||||||
|
String data;
|
||||||
|
String CRCChar;
|
||||||
|
String CRCValue;
|
||||||
|
String makeStr;
|
||||||
|
|
||||||
|
if (value.length() < 3) {return false;}
|
||||||
|
|
||||||
|
data = value.substring(0, value.length() - 3);
|
||||||
|
CRCChar = value.substring(value.length() - 3, value.length() - 2);
|
||||||
|
CRCValue = value.substring(value.length() - 2, value.length());
|
||||||
|
|
||||||
|
if (!CRCChar.equals(seperator)) {return false;}
|
||||||
|
|
||||||
|
makeStr = makeCRC(data);
|
||||||
|
|
||||||
|
if (makeStr.equals(CRCValue)) {return true;}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String fillString(int digit, String changeStr, boolean isLeft) {
|
||||||
|
String result = "";
|
||||||
|
|
||||||
|
result = changeStr;
|
||||||
|
|
||||||
|
if (isLeft) {
|
||||||
|
result = String.format("%" + String.valueOf(digit) + "s", changeStr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = String.format("%-" + String.valueOf(digit) + "s", changeStr);
|
||||||
|
}
|
||||||
|
result = result.substring(0, digit);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String byteArrayToHexString(byte[] bytes){
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
for(byte b : bytes){
|
||||||
|
|
||||||
|
sb.append(String.format("%02X ", b&0xff));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* int를 바이너리 스트링으로 변환하고 , length 에 부족한 길이만큼 0으로 채움
|
||||||
|
*
|
||||||
|
* @param a
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String IntToBinaryString(int a, int length) {
|
||||||
|
String bin = Integer.toBinaryString(a);
|
||||||
|
int offset = length - bin.length();
|
||||||
|
|
||||||
|
if (offset < 0) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < offset; i++) {
|
||||||
|
bin = "0" + bin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 바이너리 스트링을 바이트로 변환
|
||||||
|
*
|
||||||
|
* @param s
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static byte binaryStringToByte(String s) {
|
||||||
|
byte ret = 0, total = 0;
|
||||||
|
for (int i = 0; i < 8; ++i) {
|
||||||
|
ret = (s.charAt(7 - i) == '1') ? (byte) (1 << i) : 0;
|
||||||
|
total = (byte) (ret | total);
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 바이너리 스트링을 바이트배열로 변환
|
||||||
|
*
|
||||||
|
* @param s
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static byte[] binaryStringToByteArray(String s) {
|
||||||
|
int count = s.length() / 8;
|
||||||
|
byte[] b = new byte[count];
|
||||||
|
for (int i = 1; i <= count; ++i) {
|
||||||
|
String t = s.substring((i - 1) * 8, i * 8);
|
||||||
|
b[i - 1] = binaryStringToByte(t);
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 바이너리스트링을 Base64로 인코딩
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String encodeBase64(String data) {
|
||||||
|
byte[] b = binaryStringToByteArray(data);
|
||||||
|
String p = Base64.getEncoder().encodeToString(b);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 바이너리 바이트 배열을 스트링으로 변환
|
||||||
|
*
|
||||||
|
* @param b
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String byteArrayToBinaryString(byte[] b) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < b.length; ++i) {
|
||||||
|
sb.append(byteToBinaryString(b[i]));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 바이너리 바이트를 스트링으로 변환
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String byteToBinaryString(byte n) {
|
||||||
|
StringBuilder sb = new StringBuilder("00000000");
|
||||||
|
for (int bit = 0; bit < 8; bit++) {
|
||||||
|
if (((n >> bit) & 1) > 0) {
|
||||||
|
sb.setCharAt(7 - bit, '1');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base64를 바이너리스트링으로 디코딩
|
||||||
|
*
|
||||||
|
* @param s
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String decodeBase64(String s) {
|
||||||
|
byte[] decodedBytes = Base64.getDecoder().decode(s);
|
||||||
|
String p = byteArrayToBinaryString(decodedBytes);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 바이너리스트링을 Integer로 변환
|
||||||
|
*
|
||||||
|
* @param Binary
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Integer BinaryToInteger(String Binary) {
|
||||||
|
int ResutValue = 0;
|
||||||
|
boolean chk = false;
|
||||||
|
String ComvertBinary = "";
|
||||||
|
String StrBinary = Binary.replaceAll(" ", "");
|
||||||
|
String[] ArrayValue = StrBinary.split("");
|
||||||
|
|
||||||
|
switch (ArrayValue[0]) {
|
||||||
|
case "0":
|
||||||
|
ResutValue = Integer.parseInt(StrBinary, 2);
|
||||||
|
break;
|
||||||
|
case "1":
|
||||||
|
for (int i = ArrayValue.length-1; i >= 1; i--) {
|
||||||
|
if (ArrayValue[i].equals("1") && !chk) {
|
||||||
|
ComvertBinary = "1" + ComvertBinary;
|
||||||
|
chk = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chk) {
|
||||||
|
switch (ArrayValue[i]) {
|
||||||
|
case "0":
|
||||||
|
ComvertBinary = "1" + ComvertBinary;
|
||||||
|
break;
|
||||||
|
case "1":
|
||||||
|
ComvertBinary = "0" + ComvertBinary;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ComvertBinary = "0" + ComvertBinary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ResutValue = Integer.parseInt(ComvertBinary, 2) * -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return ResutValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 16진수 문자열(Hex String)을 Int배열로 변환
|
||||||
|
*
|
||||||
|
* @param inputStr
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int[] hexStringToIntArray(String inputStr) {
|
||||||
|
int[] intArray;
|
||||||
|
int strLen = inputStr.length();
|
||||||
|
|
||||||
|
if (strLen % 2 != 0) {
|
||||||
|
inputStr = inputStr.substring(0, strLen - 1) + "0"
|
||||||
|
+ inputStr.substring(strLen - 1, strLen);
|
||||||
|
strLen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
intArray = new int[strLen / 2];
|
||||||
|
int ctr = 0;
|
||||||
|
for (int n = 0; n < strLen; n += 2) {
|
||||||
|
intArray[ctr] = Integer.valueOf(inputStr.substring(n, n + 2), 16);
|
||||||
|
ctr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* int[] --> CRC16CCITT
|
||||||
|
*
|
||||||
|
* @param intArray
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String CRC16CCITT(int[] intArray) {
|
||||||
|
int crc = 0x0000; // initial value
|
||||||
|
int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
|
||||||
|
|
||||||
|
for (int a : intArray) {
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
boolean bit = ((a >> (7-i) & 1) == 1);
|
||||||
|
boolean c15 = ((crc >> 15 & 1) == 1);
|
||||||
|
crc <<= 1;
|
||||||
|
if (c15 ^ bit) crc ^= polynomial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
crc &= 0xFFFF;
|
||||||
|
String crcStr = Integer.toHexString(crc).toUpperCase();
|
||||||
|
return crcStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 바이너리스트링 --> CRC16CCITT
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String CRC16CCITT(String binary) {
|
||||||
|
int crc = 0x0000; // initial value
|
||||||
|
int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
|
||||||
|
|
||||||
|
byte[] bytes = binaryStringToByteArray(binary);
|
||||||
|
int[] intArray = new int[bytes.length];
|
||||||
|
int ctr=0;
|
||||||
|
for(byte b : bytes){
|
||||||
|
intArray[ctr] = b & 0xFF;
|
||||||
|
ctr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int a : intArray) {
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
boolean bit = ((a >> (7-i) & 1) == 1);
|
||||||
|
boolean c15 = ((crc >> 15 & 1) == 1);
|
||||||
|
crc <<= 1;
|
||||||
|
if (c15 ^ bit) crc ^= polynomial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
crc &= 0xFFFF;
|
||||||
|
String crcStr = Integer.toHexString(crc).toUpperCase();
|
||||||
|
return crcStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CRC16_CCITT 생성함수
|
||||||
|
*
|
||||||
|
* @param inputStr
|
||||||
|
* @param isBinary (inputStr 이 binary String 이면 true)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String makeCRC16_CCITT(String inputStr , boolean isBinary) {
|
||||||
|
int crc = 0x0000; // initial value
|
||||||
|
int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
|
||||||
|
int[] intArray;
|
||||||
|
int ctr;
|
||||||
|
String crcStr;
|
||||||
|
|
||||||
|
// 입력 String 타입에 따른 int array 생성
|
||||||
|
if (isBinary) {
|
||||||
|
byte[] bytes = binaryStringToByteArray(inputStr);
|
||||||
|
intArray = new int[bytes.length];
|
||||||
|
ctr=0;
|
||||||
|
for(byte b : bytes){
|
||||||
|
intArray[ctr] = b & 0xFF;
|
||||||
|
ctr++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
intArray = new int[inputStr.getBytes().length];
|
||||||
|
ctr=0;
|
||||||
|
for(byte b : inputStr.getBytes()){
|
||||||
|
intArray[ctr] = b;
|
||||||
|
ctr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// crc16_ccitt 생성 로직
|
||||||
|
for (int a : intArray) {
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
boolean bit = ((a >> (7-i) & 1) == 1);
|
||||||
|
boolean c15 = ((crc >> 15 & 1) == 1);
|
||||||
|
crc <<= 1;
|
||||||
|
if (c15 ^ bit) crc ^= polynomial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crc &= 0xFFFF;
|
||||||
|
|
||||||
|
// 입력 String 타입과 동일한 결과값 생성
|
||||||
|
if (isBinary) {
|
||||||
|
// int 를 16자리 바이트 스트링으로 변경
|
||||||
|
crcStr = String.format("%16s", Integer.toBinaryString(crc)).replace(' ', '0');
|
||||||
|
|
||||||
|
System.out.println("crcHex = "+Integer.toHexString(crc).toUpperCase());
|
||||||
|
System.out.println("crcBinary = "+crcStr);
|
||||||
|
} else {
|
||||||
|
String crcHex = Integer.toHexString(crc).toUpperCase();
|
||||||
|
System.out.println("crcHex = "+crcHex);
|
||||||
|
crcStr = hexToAscii(crcHex);
|
||||||
|
System.out.println("crcAscii = "+crcStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return crcStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CRC16 체크 함수
|
||||||
|
*
|
||||||
|
* @param packet
|
||||||
|
* @param isBinary
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean checkCRC16_CCITT(String packet, boolean isBinary) {
|
||||||
|
String msg;
|
||||||
|
String crc;
|
||||||
|
boolean isCrc;
|
||||||
|
|
||||||
|
if (isBinary) {
|
||||||
|
int len = packet.length();
|
||||||
|
|
||||||
|
msg = packet.substring(0, len-64);
|
||||||
|
crc = packet.substring(len-64, len-48);
|
||||||
|
} else {
|
||||||
|
String[] packetArray = packet.split("\\*");
|
||||||
|
msg = packetArray[0];
|
||||||
|
crc = packetArray[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
String tempCrc = makeCRC16_CCITT(msg, isBinary);
|
||||||
|
|
||||||
|
if (crc.equals(tempCrc)) isCrc = true;
|
||||||
|
else isCrc = false;
|
||||||
|
|
||||||
|
return isCrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hex String을 Ascii로 변환
|
||||||
|
*
|
||||||
|
* @param hexStr
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String hexToAscii(String hexStr) {
|
||||||
|
StringBuilder output = new StringBuilder("");
|
||||||
|
|
||||||
|
for (int i = 0; i < hexStr.length(); i += 2) {
|
||||||
|
String str = hexStr.substring(i, i + 2);
|
||||||
|
output.append((char) Integer.parseInt(str, 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 위경도를 도분초로 변환
|
||||||
|
*
|
||||||
|
* @return string[] 도, 분, 초
|
||||||
|
*/
|
||||||
|
public static String[] CoordinateToWGS84(Double LonLat, Boolean BLon) {
|
||||||
|
String[] result = new String[3];
|
||||||
|
|
||||||
|
double pDo = Math.floor(LonLat);
|
||||||
|
result[0] = String.format("%.0f", Math.abs(pDo));
|
||||||
|
|
||||||
|
double Temp = (Math.abs(LonLat) - Math.abs(pDo)) * 60.0;
|
||||||
|
|
||||||
|
double pBun = Math.floor(Temp);
|
||||||
|
if (pBun == 0) {
|
||||||
|
result[1] = "00";
|
||||||
|
} else {
|
||||||
|
result[1] = String.format("%.0f", pBun);
|
||||||
|
}
|
||||||
|
|
||||||
|
Temp = (Temp - pBun) * 60.0;
|
||||||
|
double pCho = Temp;
|
||||||
|
|
||||||
|
if (pCho == 0) {
|
||||||
|
result[2] = "00";
|
||||||
|
} else {
|
||||||
|
result[2] = String.format("%.0f", pCho);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UTC 시간을 KST로 변환
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String UtcToKst(String yyyyMMddHHmiss) {
|
||||||
|
int yyyy = Integer.parseInt(yyyyMMddHHmiss.substring(0 ,4));
|
||||||
|
int MM = Integer.parseInt(yyyyMMddHHmiss.substring(4 ,6));
|
||||||
|
int dd = Integer.parseInt(yyyyMMddHHmiss.substring(6 ,8));
|
||||||
|
int HH = Integer.parseInt(yyyyMMddHHmiss.substring(8 ,10));
|
||||||
|
int mi = Integer.parseInt(yyyyMMddHHmiss.substring(10,12));
|
||||||
|
int ss = Integer.parseInt(yyyyMMddHHmiss.substring(12,14));
|
||||||
|
|
||||||
|
SimpleDateFormat dtformat = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||||
|
Calendar date = new GregorianCalendar(yyyy, MM-1, dd, HH, mi, ss);
|
||||||
|
date.add(Calendar.HOUR_OF_DAY, 9);
|
||||||
|
|
||||||
|
Date data = date.getTime();
|
||||||
|
String strDate = dtformat.format(data);
|
||||||
|
return strDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UTC 시간을 KST로 변환(+특정 분)
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String UtcToKst_Before(String yyyyMMddHHmiss, int minutes) {
|
||||||
|
int yyyy = Integer.parseInt(yyyyMMddHHmiss.substring(0 ,4));
|
||||||
|
int MM = Integer.parseInt(yyyyMMddHHmiss.substring(4 ,6));
|
||||||
|
int dd = Integer.parseInt(yyyyMMddHHmiss.substring(6 ,8));
|
||||||
|
int HH = Integer.parseInt(yyyyMMddHHmiss.substring(8 ,10));
|
||||||
|
int mi = Integer.parseInt(yyyyMMddHHmiss.substring(10,12));
|
||||||
|
int ss = Integer.parseInt(yyyyMMddHHmiss.substring(12,14));
|
||||||
|
|
||||||
|
SimpleDateFormat dtformat = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||||
|
Calendar date = new GregorianCalendar(yyyy, MM-1, dd, HH, mi, ss);
|
||||||
|
date.add(Calendar.MINUTE, minutes);
|
||||||
|
date.add(Calendar.HOUR_OF_DAY, 9);
|
||||||
|
|
||||||
|
Date data = date.getTime();
|
||||||
|
String strDate = dtformat.format(data);
|
||||||
|
return strDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 문자형 시간 분 계산(+특정 분)
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String StrDateTimeIncMin(String yyyyMMddHHmiss, int minutes) {
|
||||||
|
int yyyy = Integer.parseInt(yyyyMMddHHmiss.substring(0 ,4));
|
||||||
|
int MM = Integer.parseInt(yyyyMMddHHmiss.substring(4 ,6));
|
||||||
|
int dd = Integer.parseInt(yyyyMMddHHmiss.substring(6 ,8));
|
||||||
|
int HH = Integer.parseInt(yyyyMMddHHmiss.substring(8 ,10));
|
||||||
|
int mi = Integer.parseInt(yyyyMMddHHmiss.substring(10,12));
|
||||||
|
int ss = Integer.parseInt(yyyyMMddHHmiss.substring(12,14));
|
||||||
|
|
||||||
|
SimpleDateFormat dtformat = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||||
|
Calendar date = new GregorianCalendar(yyyy, MM-1, dd, HH, mi, ss);
|
||||||
|
date.add(Calendar.MINUTE, minutes);
|
||||||
|
|
||||||
|
Date data = date.getTime();
|
||||||
|
String strDate = dtformat.format(data);
|
||||||
|
return strDate;
|
||||||
|
}
|
||||||
|
public static String makeCRC(byte[] value) {
|
||||||
|
byte checkSum = 0;
|
||||||
|
|
||||||
|
for(int i = 1; i < value.length; ++i) {
|
||||||
|
checkSum ^= value[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.format("%02X", checkSum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1바이트 00 체크섬 생성 함수
|
||||||
|
*
|
||||||
|
* @param s
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String makeCheckSum(String s) {
|
||||||
|
int mod = s.length() % 8;
|
||||||
|
int sum = 0;
|
||||||
|
String t="";
|
||||||
|
|
||||||
|
if (mod != 0) {
|
||||||
|
System.out.println("입력값이 바이트 단위가 아닙니다.");
|
||||||
|
} else {
|
||||||
|
for (int i=0; i<s.length(); i+=8){
|
||||||
|
String b = s.substring(i, i+8);
|
||||||
|
System.out.println("b = " + b);
|
||||||
|
sum += Integer.parseInt(b, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
String Hexsum = Integer.toHexString(sum);
|
||||||
|
String hex = Hexsum.substring(Hexsum.length()-2, Hexsum.length());
|
||||||
|
int a = Integer.parseInt(hex, 16);
|
||||||
|
String bin = Integer.toBinaryString(a);
|
||||||
|
|
||||||
|
int cnt = 8 - bin.length();
|
||||||
|
if ( bin.length() < 8) {
|
||||||
|
for(int i=0; i<cnt; i++){
|
||||||
|
bin = "0" + bin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int pos = 7;
|
||||||
|
for(int i=0; i<8; i++){
|
||||||
|
if (pos > i) {
|
||||||
|
if (bin.charAt(7-i) == '1') {
|
||||||
|
t = "1" + t;
|
||||||
|
pos = i;
|
||||||
|
} else {
|
||||||
|
t = "0" + t;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (bin.charAt(7-i) == '1') {
|
||||||
|
t = "0" + t;
|
||||||
|
} else {
|
||||||
|
t = "1" + t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// checksum = Integer.parseInt(t, 2);
|
||||||
|
|
||||||
|
// String CheckHex = Integer.toHexString(checksum).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 체크섬 검증 함수
|
||||||
|
*
|
||||||
|
* @param s
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean checkCheckSum(String s) {
|
||||||
|
boolean isCheck;
|
||||||
|
String data = s.substring(0, s.length()-3);
|
||||||
|
String checksum = s.substring(s.length()-2, s.length());
|
||||||
|
|
||||||
|
String temp = makeCRC(data.toString().getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
if (checksum.equals(temp)) {
|
||||||
|
isCheck = true;
|
||||||
|
} else {
|
||||||
|
isCheck = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HexString To ByteArray
|
||||||
|
*
|
||||||
|
* @param s(Hex String)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static byte[] hexStringToByteArray(String s) {
|
||||||
|
int len = s.length();
|
||||||
|
byte[] data = new byte[len / 2];
|
||||||
|
for (int i = 0; i < len; i += 2) {
|
||||||
|
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,248 @@
|
||||||
|
package kr.gmtc.gw.comp.socket.vo;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
public class MsgObjVO {
|
||||||
|
|
||||||
|
private int msgSeq;
|
||||||
|
// private String msg;
|
||||||
|
private byte[] msg;
|
||||||
|
private String recvIP;
|
||||||
|
private int recvPort;
|
||||||
|
private int recvID;
|
||||||
|
private int recvTag;
|
||||||
|
private LocalDateTime recvDT;
|
||||||
|
private int recvServerPort;
|
||||||
|
private String recvConnID;
|
||||||
|
|
||||||
|
private String destIP;
|
||||||
|
private int destPort;
|
||||||
|
private String destID;
|
||||||
|
|
||||||
|
private int sendID;
|
||||||
|
private int sendServerPort;
|
||||||
|
private String serviceClientIP;
|
||||||
|
private int serviceClientPort;
|
||||||
|
private String exceptIP;
|
||||||
|
private String sendClientIP;
|
||||||
|
private int sendClientPort;
|
||||||
|
private int serialPort;
|
||||||
|
|
||||||
|
public MsgObjVO() {
|
||||||
|
msgSeq = 0;
|
||||||
|
msg = null;
|
||||||
|
recvIP = "";
|
||||||
|
recvPort = 0;
|
||||||
|
recvID = -1;
|
||||||
|
recvTag = 0;
|
||||||
|
recvDT = LocalDateTime.now();
|
||||||
|
|
||||||
|
recvServerPort = -1;
|
||||||
|
recvConnID = "";
|
||||||
|
destIP = "";
|
||||||
|
destPort = 0;
|
||||||
|
destID = "";
|
||||||
|
|
||||||
|
sendID = -1;
|
||||||
|
sendServerPort = 0;
|
||||||
|
serviceClientIP = "";
|
||||||
|
serviceClientPort = 0;
|
||||||
|
exceptIP = "";
|
||||||
|
sendClientIP = "";
|
||||||
|
sendClientPort = 0;
|
||||||
|
serialPort = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMsgSeq() {
|
||||||
|
return msgSeq;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMsgSeq(int msgSeq) {
|
||||||
|
this.msgSeq = msgSeq;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getMsg() {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMsg(byte[] msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecvIP() {
|
||||||
|
return recvIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecvIP(String recvIP) {
|
||||||
|
this.recvIP = recvIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRecvPort() {
|
||||||
|
return recvPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecvPort(int rcvPort) {
|
||||||
|
this.recvPort = rcvPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRecvID() {
|
||||||
|
return recvID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecvID(int rcvID) {
|
||||||
|
this.recvID = rcvID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getRecvDT() {
|
||||||
|
return recvDT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecvDT(LocalDateTime localDateTime) {
|
||||||
|
this.recvDT = localDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRecvServerPort() {
|
||||||
|
return recvServerPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecvServerPort(int serverPort) {
|
||||||
|
this.recvServerPort = serverPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecvConnID() {
|
||||||
|
return recvConnID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecvConnID(String connID) {
|
||||||
|
this.recvConnID = connID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRecvTag() {
|
||||||
|
return recvTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecvTag(int tag) {
|
||||||
|
this.recvTag = tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDestIP() {
|
||||||
|
return destIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDestIP(String destIP) {
|
||||||
|
this.destIP = destIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDestPort() {
|
||||||
|
return destPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDestPort(int destPort) {
|
||||||
|
this.destPort = destPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDestID() {
|
||||||
|
return destID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDestID(String destID) {
|
||||||
|
this.destID = destID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSendID() {
|
||||||
|
return sendID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSendID(int sendID) {
|
||||||
|
this.sendID = sendID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSendServerPort() {
|
||||||
|
return sendServerPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSendServerPort(int serverPort) {
|
||||||
|
this.sendServerPort = serverPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServiceClientIP() {
|
||||||
|
return serviceClientIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServiceClientIP(String serviceClientIP) {
|
||||||
|
this.serviceClientIP = serviceClientIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getServiceClientPort() {
|
||||||
|
return serviceClientPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServiceClientPort(int serviceClientPort) {
|
||||||
|
this.serviceClientPort = serviceClientPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExceptIP() {
|
||||||
|
return exceptIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExceptIP(String exceptIP) {
|
||||||
|
this.exceptIP = exceptIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSendClientIP() {
|
||||||
|
return sendClientIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSendClientIP(String clientIP) {
|
||||||
|
this.sendClientIP = clientIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSendClientPort() {
|
||||||
|
return sendClientPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSendClientPort(int clientPort) {
|
||||||
|
this.sendClientPort = clientPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSerialPort() {
|
||||||
|
return serialPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSerialPort(int serialPort) {
|
||||||
|
this.serialPort = serialPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MsgObjVO getClone() {
|
||||||
|
try {
|
||||||
|
MsgObjVO vo = new MsgObjVO();
|
||||||
|
|
||||||
|
vo.msgSeq = this.msgSeq;
|
||||||
|
vo.msg = this.msg;
|
||||||
|
vo.recvIP = this.recvIP;
|
||||||
|
vo.recvPort = this.recvPort;;
|
||||||
|
vo.recvID = this.recvID;
|
||||||
|
vo.recvTag = this.recvTag;
|
||||||
|
vo.recvDT = this.recvDT;
|
||||||
|
vo.recvServerPort = this.recvServerPort;
|
||||||
|
vo.recvConnID = this.recvConnID;
|
||||||
|
vo.destIP = this.destIP;
|
||||||
|
vo.destPort = this.destPort;
|
||||||
|
vo.destID = this.destID;
|
||||||
|
|
||||||
|
vo.sendID = this.sendID;
|
||||||
|
vo.sendServerPort = this.sendServerPort;
|
||||||
|
vo.serviceClientIP = this.serviceClientIP;
|
||||||
|
vo.serviceClientPort = this.serviceClientPort;
|
||||||
|
vo.exceptIP = this.exceptIP;
|
||||||
|
vo.sendClientIP = this.sendClientIP;
|
||||||
|
vo.sendClientPort = this.sendClientPort;
|
||||||
|
vo.serialPort = this.serialPort;
|
||||||
|
|
||||||
|
return vo;
|
||||||
|
} catch(Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
package kr.gmtc.gw.comp.socket.vo;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import kr.gmtc.gw.comp.socket.type.NetStatType;
|
||||||
|
|
||||||
|
public class NetStatVO {
|
||||||
|
private LocalDateTime sendExecuteTime;
|
||||||
|
private LocalDateTime recvExecuteTime;
|
||||||
|
private LocalDateTime wbExecuteTime;
|
||||||
|
private LocalDateTime wouldBlockFromTime;
|
||||||
|
private LocalDateTime wouldBlockToTime;
|
||||||
|
private String description;
|
||||||
|
private LocalDateTime lastSendTime;
|
||||||
|
private LocalDateTime errorTime;
|
||||||
|
private int retryCount;
|
||||||
|
private NetStatType stat;
|
||||||
|
|
||||||
|
public NetStatVO() {
|
||||||
|
sendExecuteTime = LocalDateTime.now();
|
||||||
|
recvExecuteTime = LocalDateTime.now();
|
||||||
|
wbExecuteTime = LocalDateTime.now();
|
||||||
|
wouldBlockFromTime = LocalDateTime.now();
|
||||||
|
wouldBlockToTime = LocalDateTime.now();
|
||||||
|
description = "";
|
||||||
|
lastSendTime = LocalDateTime.now();
|
||||||
|
errorTime = LocalDateTime.now();
|
||||||
|
retryCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetStatType getStat() {
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStat(NetStatType stat) {
|
||||||
|
this.stat = stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getSendExecuteTime() {
|
||||||
|
return sendExecuteTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSendExecuteTime(LocalDateTime sendExecuteTime) {
|
||||||
|
this.sendExecuteTime = sendExecuteTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getRecvExecuteTime() {
|
||||||
|
return recvExecuteTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecvExecuteTime(LocalDateTime recvExecuteTime) {
|
||||||
|
this.recvExecuteTime = recvExecuteTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getWbExecuteTime() {
|
||||||
|
return wbExecuteTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWbExecuteTime(LocalDateTime wbExecuteTime) {
|
||||||
|
this.wbExecuteTime = wbExecuteTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getWouldBlockFromTime() {
|
||||||
|
return wouldBlockFromTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWouldBlockFromTime(LocalDateTime wouldBlockFromTime) {
|
||||||
|
this.wouldBlockFromTime = wouldBlockFromTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getWouldBlockToTime() {
|
||||||
|
return wouldBlockToTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWouldBlockToTime(LocalDateTime wouldBlockToTime) {
|
||||||
|
this.wouldBlockToTime = wouldBlockToTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getLastSendTime() {
|
||||||
|
return lastSendTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastSendTime(LocalDateTime lastSendTime) {
|
||||||
|
this.lastSendTime = lastSendTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getErrorTime() {
|
||||||
|
return errorTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setErrorTime(LocalDateTime errorTime) {
|
||||||
|
this.errorTime = errorTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRetryCount() {
|
||||||
|
return retryCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRetryCount(int retryCount) {
|
||||||
|
this.retryCount = retryCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
package kr.gmtc.gw.comp.thread;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import kr.gmtc.gw.comp.thread.handler.CustomThreadOnTerminate;
|
||||||
|
import kr.gmtc.gw.comp.thread.handler.CustomThreadWork;
|
||||||
|
|
||||||
|
public class CustomThread extends Thread{
|
||||||
|
|
||||||
|
/* 대기시간 없음 */
|
||||||
|
public static final long NO_SLEEP = 0;
|
||||||
|
/* 1밀리 초 */
|
||||||
|
public static final long SLEEP_MILLI_SEC = 1;
|
||||||
|
/* 1초 */
|
||||||
|
public static final long SLEEP_SECOND = 1000;
|
||||||
|
/* 30초 */
|
||||||
|
public static final long SLEEP_HALF_MINIUTE = 30000;
|
||||||
|
/* 1분 */
|
||||||
|
public static final long SLEEP_MINIUTE = 60000;
|
||||||
|
|
||||||
|
public final String controllClassName;
|
||||||
|
public final long repeatMiliSec;
|
||||||
|
public final CustomThreadWork definedWork;
|
||||||
|
public final CustomThreadOnTerminate definedTerminate;
|
||||||
|
public final Logger logger;
|
||||||
|
private boolean running;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 인터럽트를 받을 시 스레드가 종료됨.<br>
|
||||||
|
* {@link Thread#sleep(long)} 기반으로 재실행 간격을 설정하므로 정확한 실행시간을 보장하지 않음.<br>
|
||||||
|
* 정확한 실행시간 보장이 필요 할 경우 sleep 간격을 짧게 설정하고 호출위치에서 시간확인<br>
|
||||||
|
* 정상적인 종료는 {@link #gracefulStop()}으로 종료함
|
||||||
|
* @param threadName 스레드 이름
|
||||||
|
* @param controllClass 스레드 관리 클래스, 일반적으로 this 사용
|
||||||
|
* @param repeatMiliSec Sleep 시간(밀리 초), 0이하의 경우 대기시간 없음
|
||||||
|
* @param definedWork 반복할 작업
|
||||||
|
* @param definedTerminate 스레드가 인터럽트에 의해 종료될 경우 할 작업
|
||||||
|
* @param autoStart 생성즉시 실행
|
||||||
|
*/
|
||||||
|
|
||||||
|
public CustomThread(String threadName, Object controllClass, long repeatMiliSec,
|
||||||
|
CustomThreadWork definedWork, CustomThreadOnTerminate definedTerminate, boolean autoStart) {
|
||||||
|
|
||||||
|
if (definedWork == null) {
|
||||||
|
throw new IllegalArgumentException("[CustomThread] - definedWork is null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.definedWork = definedWork;
|
||||||
|
this.definedTerminate = definedTerminate;
|
||||||
|
this.controllClassName = controllClass == null ? "" : controllClass.getClass().getSimpleName();
|
||||||
|
this.repeatMiliSec = repeatMiliSec > 0 ? repeatMiliSec : 0;
|
||||||
|
this.logger = LoggerFactory.getLogger(CustomThread.class);
|
||||||
|
this.running = false;
|
||||||
|
|
||||||
|
setName(threadName);
|
||||||
|
setDaemon(true);
|
||||||
|
if (autoStart) {
|
||||||
|
this.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
logger.info("[CustomThread] Started.");
|
||||||
|
while ( this.running && !this.isInterrupted()) {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
this.definedWork.work();
|
||||||
|
} finally {
|
||||||
|
if (this.repeatMiliSec > 0) {
|
||||||
|
Thread.sleep(this.repeatMiliSec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(InterruptedException e) { // 인터럽트 수신시 종료
|
||||||
|
logger.error("[CustomThread] Interrupted. "+ e.toString());
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
break;
|
||||||
|
} catch(Exception e) { // 처리되지 않은 예외 로깅, 예외에 의한 무한루프에 주의
|
||||||
|
logger.error("[CustomThread] Unknown Exception Occur. " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.definedTerminate != null) {
|
||||||
|
this.definedTerminate.onTerminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.error("[CustomThread] Stoped.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
|
||||||
|
return "CustomThread [controllClass=" + this.controllClassName + ", threadName=" + getName() +
|
||||||
|
", runnig=" + this.running + ", alive=" + isAlive()+ ", repeatMiliSec=" + this.repeatMiliSec +
|
||||||
|
", definedTerminate=" + (this.definedTerminate == null ? "no" : "yes") + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void start() {
|
||||||
|
this.running = true;
|
||||||
|
super.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 스레드 정상종료, 진행중인 작업 완료 후 종료됨.
|
||||||
|
*/
|
||||||
|
public void gracefulStop() {
|
||||||
|
this.running = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package kr.gmtc.gw.comp.thread.handler;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface CustomThreadOnTerminate {
|
||||||
|
public void onTerminate();
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package kr.gmtc.gw.comp.thread.handler;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface CustomThreadWork {
|
||||||
|
public void work() throws Exception;
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
{"properties": [
|
||||||
|
{
|
||||||
|
"name": "root",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'root'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asde.filepath1",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'asde.filepath1'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asde.filepath2",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'asde.filepath2'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asde.service",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'asde.service'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asde.service.queueCount",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'asde.queueCount'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asde.service.clearQ.max-count",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'asde.clearQ.max-count'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asde.service.clearQ.diff-time",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'asde.clearQ.diff-time'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asde.service.clearQ.clearTime",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'asde.clearQ.clearTime'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dev.debug.debugLogMode",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'dev.debug.debugLogMode'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "database.db1.datasource.driver-class-name",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'database.db1.datasource.driver-class-name'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "database.db1.datasource.password",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'database.db1.datasource.password'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "database.db1.datasource.jdbcUrl",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'database.db1.datasource.jdbcUrl'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "database.db1.datasource.username",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'database.db1.datasource.username'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "kafka.settings",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'kafka.settings'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "kafka.bootstrapAddress",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'kafka.bootstrapAddress'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "kafka.consumer.group-id",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'kafka.consumer.group-id'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "kafka.producer.key-serializer",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'kafka.producer.key-serializer'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "kafka.producer.value-serializer",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "A description for 'kafka.producer.value-serializer'"
|
||||||
|
}
|
||||||
|
]}
|
|
@ -0,0 +1,71 @@
|
||||||
|
spring:
|
||||||
|
profiles:
|
||||||
|
active: default
|
||||||
|
group:
|
||||||
|
default:
|
||||||
|
- winTest
|
||||||
|
|
||||||
|
---
|
||||||
|
spring:
|
||||||
|
config:
|
||||||
|
activate:
|
||||||
|
on-profile: default
|
||||||
|
|
||||||
|
server:
|
||||||
|
port: 18080
|
||||||
|
|
||||||
|
asde:
|
||||||
|
service:
|
||||||
|
queueCount: 3
|
||||||
|
serviceCount: 5000
|
||||||
|
clearQ:
|
||||||
|
maxCount: 20000 # 2만건
|
||||||
|
diffTime: 10000 # 10 sec
|
||||||
|
clearTime: 60000 # milli-Sec, 1분
|
||||||
|
|
||||||
|
state:
|
||||||
|
# 공통코드 CT001의 코드 6자리
|
||||||
|
id: LK0401
|
||||||
|
# 1:Primary, 2:Secondary
|
||||||
|
type: Primary
|
||||||
|
|
||||||
|
---
|
||||||
|
spring:
|
||||||
|
config:
|
||||||
|
activate:
|
||||||
|
on-profile: real
|
||||||
|
|
||||||
|
root: /home/gmt/app/EyeGW_AsdeRecv
|
||||||
|
|
||||||
|
---
|
||||||
|
spring:
|
||||||
|
config:
|
||||||
|
activate:
|
||||||
|
on-profile: winTest
|
||||||
|
|
||||||
|
# none = parsing 결과 표출 안함
|
||||||
|
# line = parsing 결과 한줄 표시
|
||||||
|
# detail = parsing 결과 상세 표시
|
||||||
|
dev:
|
||||||
|
debug:
|
||||||
|
debugLogMode: none
|
||||||
|
|
||||||
|
root: D:\Workspace\Odroid_repository\EyeGW_AsdeRecv
|
||||||
|
|
||||||
|
database:
|
||||||
|
db1:
|
||||||
|
datasource:
|
||||||
|
driver-class-name: com.tmax.tibero.jdbc.TbDriver
|
||||||
|
jdbcUrl: jdbc:tibero:thin:@10.200.31.1:8629:sacp
|
||||||
|
username: ueai
|
||||||
|
password: ueai
|
||||||
|
|
||||||
|
kafka:
|
||||||
|
settings:
|
||||||
|
bootstrapAddress: 118.220.143.175:9091,118.220.143.175:9091,118.220.143.176:9092
|
||||||
|
consumer:
|
||||||
|
group-id: testgroup
|
||||||
|
producer:
|
||||||
|
key-serializer: org.apache.kafka.common.serialization.StringSerializer
|
||||||
|
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<AsterixListCategory>
|
||||||
|
<AsterixSpecFile category="10" file="spec/alterixCat010Indra.yml" />
|
||||||
|
<AsterixSpecFile category="11" file="spec/alterixCat011.yml" />
|
||||||
|
</AsterixListCategory>
|
|
@ -0,0 +1,111 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration scan="true" scanPeriod="30 seconds">
|
||||||
|
|
||||||
|
<property name="PATH_SEPARATOR" value="/"/>
|
||||||
|
|
||||||
|
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
|
||||||
|
|
||||||
|
<!-- 로그 파일이 저장될 경로 -->
|
||||||
|
<property name="LOG_PATH" value=".${PATH_SEPARATOR}logs"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 로그 파일 이름 -->
|
||||||
|
<property name="LOG_FILE_NAME" value="trace"/>
|
||||||
|
|
||||||
|
<!-- 로그 출력 패턴 -->
|
||||||
|
<property name="LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] %highlight([%.-1level]) %clr([%-40.40(%class{0}.%method)]){cyan} %msg%n"/>
|
||||||
|
<property name="FILE_LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}][%.-1level][%-40.40(%class{0}.%method)] %msg%n"/>
|
||||||
|
|
||||||
|
<!-- 로그 레벨 -->
|
||||||
|
<!--
|
||||||
|
1) ERROR : 오류 메시지 표시
|
||||||
|
2) WARN : 경고성 메시지 표시
|
||||||
|
3) INFO : 정보성 메시지 표시
|
||||||
|
4) DEBUG : 디버깅하기 위한 메시지 표시
|
||||||
|
5) TRACE : Debug보다 훨씬 상세한 메시지 표시
|
||||||
|
-->
|
||||||
|
<property name="LOG_LEVEL" value="INFO"/>
|
||||||
|
|
||||||
|
<!-- CONSOLE에 로그 출력 세팅 -->
|
||||||
|
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||||
|
<pattern>${LOG_PATTERN}</pattern>
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="CUSTOM" class="kr.gmtc.gw.asderecv.logger.CustomAppender">
|
||||||
|
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||||
|
<pattern>${LOG_PATTERN}</pattern>
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- File에 로그 출력 세팅 -->
|
||||||
|
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
|
||||||
|
<!-- 로그파일은 Info부터 저장한다!! -->
|
||||||
|
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||||
|
<!-- <level>INFO</level> -->
|
||||||
|
<level>INFO</level>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- 파일 경로 설정 -->
|
||||||
|
<file>${LOG_PATH}${PATH_SEPARATOR}${LOG_FILE_NAME}.log</file>
|
||||||
|
|
||||||
|
<!-- 출력패턴 설정-->
|
||||||
|
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||||
|
<pattern>${FILE_LOG_PATTERN}</pattern>
|
||||||
|
</layout>
|
||||||
|
|
||||||
|
<!-- Rolling 정책 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- .gz,.zip 등을 넣으면 자동 일자별 로그파일 압축 -->
|
||||||
|
<fileNamePattern>${LOG_PATH}${PATH_SEPARATOR}%d{yyyyMM,aux}${PATH_SEPARATOR}%d{yyyyMMdd}.log</fileNamePattern>
|
||||||
|
<!-- 로그파일 최대 보관주기, fileNamePattern 에 따라 일별, 월별, 년별-->
|
||||||
|
<maxHistory>10</maxHistory>
|
||||||
|
<!-- 아카이브 최대 용량 maxHistory 이후에 적용됨 -->
|
||||||
|
<totalSizeCap>100mb</totalSizeCap>
|
||||||
|
<!-- 시작시 정책 적용 여부 -->
|
||||||
|
<CleanHistoryOnStart>true</CleanHistoryOnStart>
|
||||||
|
</rollingPolicy>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 비동기 파일(FILE)
|
||||||
|
includeCallerData: fasle, 비동기 로깅에서도 Method Name 및 Line Number 등 위치 정보를 출력하게 해주는 옵션
|
||||||
|
queueSize: 기본값은 256, Log4j2와 동일하게 1024로 설정
|
||||||
|
neverBlock: false(기본값)면 로그 발생시 Queue에 넣을 공간이 없으면 빈 공간이 생길 때 까지 블락킹 상태로 기다리며, 로그를 유실하지 않는다.
|
||||||
|
discardingThreshold: Queue에 남은 용량이 {해당 설정값 n}%이하가 되면, WARN 미만 로그가 유실되기 시작한다.
|
||||||
|
- 기본 값은 20이며, Queue 남은 용량이 20%이하가 되면 로그 유실이 발생한다.
|
||||||
|
- 0으로 세팅하면 Queue에 쌓인 로그를 드랍하지 않는다.
|
||||||
|
-->
|
||||||
|
<appender name="FILE-ASYNC" class="ch.qos.logback.classic.AsyncAppender">
|
||||||
|
<appender-ref ref="FILE" />
|
||||||
|
<includeCallerData>false</includeCallerData>
|
||||||
|
<discardingThreshold>0</discardingThreshold>
|
||||||
|
<queueSize>1024</queueSize>
|
||||||
|
<neverBlock>true</neverBlock>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 로그 전역 세팅 -->
|
||||||
|
<!-- <root level="${LOG_LEVEL}">
|
||||||
|
<appender-ref ref="CONSOLE"/>
|
||||||
|
<appender-ref ref="FILE"/>
|
||||||
|
</root> -->
|
||||||
|
|
||||||
|
<logger name="kr.gmtc.gw" level="TRACE">
|
||||||
|
<appender-ref ref="CONSOLE"/>
|
||||||
|
<appender-ref ref="FILE"/>
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<logger name="kr.gmt.so" level="INFO">
|
||||||
|
<appender-ref ref="CONSOLE"/>
|
||||||
|
<appender-ref ref="FILE"/>
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<!-- <logger name="kr.gmtc.comp.status" level="TRACE">
|
||||||
|
<appender-ref ref="CONSOLE"/>
|
||||||
|
<appender-ref ref="FILE"/>
|
||||||
|
</logger> -->
|
||||||
|
|
||||||
|
</configuration>
|
|
@ -0,0 +1,735 @@
|
||||||
|
cat: 10
|
||||||
|
ver: 1.1_indra
|
||||||
|
dataitem:
|
||||||
|
- itemno: I010/010
|
||||||
|
frn: 1
|
||||||
|
rule: mandatory
|
||||||
|
itemdesc: Data Source Identifier
|
||||||
|
definition: Identification of the system from which the data are received.
|
||||||
|
format: fixed
|
||||||
|
octet: 2
|
||||||
|
structure:
|
||||||
|
- name: SAC
|
||||||
|
frombit: 16
|
||||||
|
tobit: 9
|
||||||
|
desc: System Area Code fixed to zero
|
||||||
|
- name: SIC
|
||||||
|
frombit: 8
|
||||||
|
tobit: 1
|
||||||
|
desc: System Identification Code
|
||||||
|
- itemno: I010/020
|
||||||
|
frn: 2
|
||||||
|
rule: mandatory
|
||||||
|
itemdesc: Target Data Type (target descriptor)
|
||||||
|
definition: Type and characteristics of the data as transmitted by a system.
|
||||||
|
format: variable
|
||||||
|
octet: 1
|
||||||
|
- itemno: I010/020-1
|
||||||
|
frn: 201
|
||||||
|
rule: mandatory
|
||||||
|
itemdesc: Target Report Descriptor
|
||||||
|
definition: Type and characteristics of the data as transmitted by a system.
|
||||||
|
format: fixed
|
||||||
|
octet: 1
|
||||||
|
structure:
|
||||||
|
- name: TYP
|
||||||
|
frombit: 8
|
||||||
|
desc: TYP
|
||||||
|
- name: DEC
|
||||||
|
frombit: 7
|
||||||
|
tobit: 6
|
||||||
|
desc: 00 default value for the SCA system.
|
||||||
|
- name: CTL
|
||||||
|
frombit: 5
|
||||||
|
codes:
|
||||||
|
0: disable the control function to perform calculation on the target
|
||||||
|
1: enable the control function to perform calculation on the target
|
||||||
|
- name: VIS
|
||||||
|
frombit: 4
|
||||||
|
desc: renamed from CHN (Chain 1/2) to VIS
|
||||||
|
codes:
|
||||||
|
0: disable the label display
|
||||||
|
1: enable the label display
|
||||||
|
- name: LAB
|
||||||
|
frombit: 3
|
||||||
|
desc: renamed from GBS (Transponder ground) to LAB
|
||||||
|
codes:
|
||||||
|
0: AUTOMATIC LABELLING
|
||||||
|
1: MANUAL LABELLING
|
||||||
|
- name: TST
|
||||||
|
frombit: 2
|
||||||
|
desc: renamed from CRT (Corrupted reply in multilateration) to TST
|
||||||
|
codes:
|
||||||
|
0: real measure
|
||||||
|
1: simulated data set
|
||||||
|
- name: EXT
|
||||||
|
frombit: 1
|
||||||
|
codes:
|
||||||
|
0: End of Data Item
|
||||||
|
1: Extension into first extent
|
||||||
|
- itemno: I010/161
|
||||||
|
frn: 3
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Track Number
|
||||||
|
definition: An integer value representing a unique reference to a track record within a particular track file.
|
||||||
|
format: fixed
|
||||||
|
octet: 2
|
||||||
|
structure:
|
||||||
|
- name: TrkNb
|
||||||
|
serviceFieldName: track_no
|
||||||
|
frombit: 16
|
||||||
|
tobit: 1
|
||||||
|
max: 65535
|
||||||
|
min: 0
|
||||||
|
desc: Track number
|
||||||
|
- itemno: I010/040
|
||||||
|
frn: 4
|
||||||
|
rule: X
|
||||||
|
itemdesc: Target position in polar coordinates
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 4
|
||||||
|
- itemno: I010/042
|
||||||
|
frn: 5
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Position in Cartesian Coordinates
|
||||||
|
definition: Position of target in Cartesian Coordinates, in two’s complement form.
|
||||||
|
format: fixed
|
||||||
|
octet: 4
|
||||||
|
structure:
|
||||||
|
- name: X-Component
|
||||||
|
serviceFieldName: lat
|
||||||
|
frombit: 32
|
||||||
|
tobit: 17
|
||||||
|
datatype: int
|
||||||
|
desc: X-Component
|
||||||
|
resolution: 0.25
|
||||||
|
min: "-8191"
|
||||||
|
max: 8191
|
||||||
|
unit: m
|
||||||
|
- name: Y-Component
|
||||||
|
serviceFieldName: lon
|
||||||
|
frombit: 16
|
||||||
|
tobit: 1
|
||||||
|
datatype: int
|
||||||
|
desc: Y-Component
|
||||||
|
resolution: 0.25
|
||||||
|
min: "-8191"
|
||||||
|
max: 8191
|
||||||
|
unit: m
|
||||||
|
- itemno: I010/200
|
||||||
|
frn: 6
|
||||||
|
rule: X
|
||||||
|
itemdesc: Target velocity in polar coordinates
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 2
|
||||||
|
- itemno: I010/202
|
||||||
|
frn: 7
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Velocity in Cartesian Coordinates
|
||||||
|
definition: Velocity in Cartesian Coordinates
|
||||||
|
format: fixed
|
||||||
|
octet: 2
|
||||||
|
structure:
|
||||||
|
- name: Vx
|
||||||
|
serviceFieldName: spd
|
||||||
|
frombit: 16
|
||||||
|
tobit: 9
|
||||||
|
desc: Vx
|
||||||
|
resolution: 1
|
||||||
|
min: "-127"
|
||||||
|
max: 127
|
||||||
|
unit: m/s
|
||||||
|
datatype: int
|
||||||
|
- name: Vy
|
||||||
|
serviceFieldName: spd
|
||||||
|
frombit: 8
|
||||||
|
tobit: 1
|
||||||
|
desc: Vy
|
||||||
|
resolution: 1
|
||||||
|
min: "-127"
|
||||||
|
max: 127
|
||||||
|
unit: m/s
|
||||||
|
datatype: int
|
||||||
|
- itemno: I010/130
|
||||||
|
frn: 8
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Track Information
|
||||||
|
definition: Track Information
|
||||||
|
format: variable
|
||||||
|
octet: 1
|
||||||
|
- itemno: I010/130-1
|
||||||
|
frn: 801
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Track Information
|
||||||
|
definition: Track Information
|
||||||
|
format: fixed
|
||||||
|
octet: 1
|
||||||
|
structure:
|
||||||
|
- name: TLE
|
||||||
|
frombit: 8
|
||||||
|
tobit: 6
|
||||||
|
desc: target size
|
||||||
|
codes:
|
||||||
|
7: Unknown size
|
||||||
|
- name: SHAPE
|
||||||
|
serviceFieldName: trgt_ty
|
||||||
|
frombit: 5
|
||||||
|
tobit: 4
|
||||||
|
desc: target size
|
||||||
|
codes:
|
||||||
|
0: To be defined
|
||||||
|
1: Vehicle (no Towing Plan linked)
|
||||||
|
2: Aircraft (no Towing Plan linked)
|
||||||
|
3: Towing (a Towing Plan is linked to the track).
|
||||||
|
- name: FLIGHT
|
||||||
|
frombit: 3
|
||||||
|
tobit: 2
|
||||||
|
desc: FLIGHT
|
||||||
|
codes:
|
||||||
|
0: Other wise
|
||||||
|
1: Inbound (arrival)
|
||||||
|
2: Outbound (departure)
|
||||||
|
3: De-icing, a departure aircraft taxying to de-icing zone or pad.
|
||||||
|
- name: EXT
|
||||||
|
frombit: 1
|
||||||
|
tobit: 1
|
||||||
|
desc: EXT
|
||||||
|
codes:
|
||||||
|
0: No extension byte
|
||||||
|
1: Extension byte
|
||||||
|
- itemno: I010/130-2
|
||||||
|
frn: 802
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Track Information
|
||||||
|
definition: Track Information
|
||||||
|
format: fixed
|
||||||
|
octet: 1
|
||||||
|
structure:
|
||||||
|
- name: XM
|
||||||
|
serviceFieldName: lat_add
|
||||||
|
frombit: 6
|
||||||
|
tobit: 6
|
||||||
|
max: 8191
|
||||||
|
min: "-8191"
|
||||||
|
- name: YM
|
||||||
|
serviceFieldName: lon_add
|
||||||
|
frombit: 5
|
||||||
|
tobit: 5
|
||||||
|
max: 8191
|
||||||
|
min: "-8191"
|
||||||
|
- name: VXM
|
||||||
|
frombit: 4
|
||||||
|
tobit: 4
|
||||||
|
max: 127
|
||||||
|
min: "-127"
|
||||||
|
- name: VYM
|
||||||
|
frombit: 3
|
||||||
|
tobit: 3
|
||||||
|
max: 127
|
||||||
|
min: "-127"
|
||||||
|
- itemno: I010/099
|
||||||
|
frn: 9
|
||||||
|
rule: X
|
||||||
|
itemdesc: Standard Instrumental Departure (SID)
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 8
|
||||||
|
- itemno: I010/170
|
||||||
|
frn: 10
|
||||||
|
rule: X
|
||||||
|
itemdesc: Track Status
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 1
|
||||||
|
- itemno: I010/141
|
||||||
|
frn: 11
|
||||||
|
rule: X
|
||||||
|
itemdesc: UTC time of day
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 3
|
||||||
|
- itemno: I010/030
|
||||||
|
frn: 12
|
||||||
|
rule: X
|
||||||
|
itemdesc: Warning / Error
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 1
|
||||||
|
- itemno: I010/270
|
||||||
|
frn: 13
|
||||||
|
rule: X
|
||||||
|
itemdesc: Target Size
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 1
|
||||||
|
- itemno: I010/150
|
||||||
|
frn: 14
|
||||||
|
rule: X
|
||||||
|
itemdesc: Presence of X-Pulse
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 1
|
||||||
|
- itemno: I010/070
|
||||||
|
frn: 15
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Mode 3/A code (SSR Code)
|
||||||
|
definition: Mode-3/A code converted into octal representation.
|
||||||
|
format: fixed
|
||||||
|
octet: 2
|
||||||
|
structure:
|
||||||
|
- name: V
|
||||||
|
frombit: 16
|
||||||
|
desc: V
|
||||||
|
codes:
|
||||||
|
0: Code validated
|
||||||
|
1: Code not validated
|
||||||
|
- name: G
|
||||||
|
frombit: 15
|
||||||
|
desc: G
|
||||||
|
codes:
|
||||||
|
0: Default
|
||||||
|
1: Garbled code
|
||||||
|
- name: L
|
||||||
|
frombit: 14
|
||||||
|
desc: L
|
||||||
|
codes:
|
||||||
|
0: Mode-2 code derived from the reply of the transponder
|
||||||
|
1: Smoothed Mode-2 code as provided by a local tracker n
|
||||||
|
- name: spare
|
||||||
|
frombit: 13
|
||||||
|
desc: Spare bit set to 0
|
||||||
|
bitsConst: 0
|
||||||
|
- name: Mod3A
|
||||||
|
serviceFieldName: ssr_cd
|
||||||
|
frombit: 12
|
||||||
|
tobit: 1
|
||||||
|
datatype: octal
|
||||||
|
desc: Mode-3/A reply in octal representation
|
||||||
|
- itemno: I010/072
|
||||||
|
frn: 16
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Call Sign (Flight Number)
|
||||||
|
definition: The call sign is coded with 8 ASCII characters.
|
||||||
|
format: fixed
|
||||||
|
octet: 8
|
||||||
|
structure:
|
||||||
|
- name: CallSign
|
||||||
|
serviceFieldName: clsgn
|
||||||
|
frombit: 64
|
||||||
|
tobit: 1
|
||||||
|
desc: CallSign
|
||||||
|
datatype: ascii
|
||||||
|
- itemno: I010/074
|
||||||
|
frn: 17
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Mode S Address
|
||||||
|
definition: The mode S address is coded on three bytes.
|
||||||
|
format: fixed
|
||||||
|
octet: 3
|
||||||
|
structure:
|
||||||
|
- name: ModeS
|
||||||
|
serviceFieldName: mode_s_cd
|
||||||
|
frombit: 24
|
||||||
|
tobit: 1
|
||||||
|
desc: ModeS
|
||||||
|
- itemno: I010/076
|
||||||
|
frn: 18
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Registration Mark (Tail Number)
|
||||||
|
definition: The registration mark is coded with 8 ASCII characters.
|
||||||
|
format: fixed
|
||||||
|
octet: 8
|
||||||
|
structure:
|
||||||
|
- name: Reg
|
||||||
|
serviceFieldName: tail_no
|
||||||
|
frombit: 64
|
||||||
|
tobit: 1
|
||||||
|
desc: Reg
|
||||||
|
datatype: ascii
|
||||||
|
- itemno: I010/300
|
||||||
|
frn: 19
|
||||||
|
rule: X
|
||||||
|
itemdesc: Position standard deviation in Cartesian Coordinates
|
||||||
|
definition: Position standard deviation in Cartesian coordinates
|
||||||
|
format: fixed
|
||||||
|
octet: 4
|
||||||
|
- itemno: I010/302
|
||||||
|
frn: 20
|
||||||
|
rule: X
|
||||||
|
itemdesc: Velocity standard deviation in Cartesian coordinates
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 2
|
||||||
|
- itemno: I010/032
|
||||||
|
frn: 21
|
||||||
|
rule: X
|
||||||
|
itemdesc: Label error
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 1
|
||||||
|
- itemno: I010/090
|
||||||
|
frn: 22
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Mode C Code (Height)
|
||||||
|
definition: Mode C height converted into binary representation on two bytes fixed length data item.
|
||||||
|
format: fixed
|
||||||
|
octet: 2
|
||||||
|
structure:
|
||||||
|
- name: V
|
||||||
|
frombit: 16
|
||||||
|
datatype: int
|
||||||
|
codes:
|
||||||
|
0: Code validated
|
||||||
|
1: Code not validated
|
||||||
|
- name: G
|
||||||
|
frombit: 15
|
||||||
|
datatype: int
|
||||||
|
codes:
|
||||||
|
0: Default value
|
||||||
|
1: Garbled code
|
||||||
|
# - name: S
|
||||||
|
# frombit: 14
|
||||||
|
# desc: sign bit
|
||||||
|
- name: FL
|
||||||
|
frombit: 14
|
||||||
|
tobit: 1
|
||||||
|
datatype: int
|
||||||
|
desc: Mode C HEIGHT
|
||||||
|
resolution: 0.25
|
||||||
|
unit: FL
|
||||||
|
serviceFieldName: alt
|
||||||
|
- itemno: I010/044
|
||||||
|
frn: 23
|
||||||
|
rule: X
|
||||||
|
itemdesc: Target heading in degrees referenced to the North.
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 1
|
||||||
|
- itemno: I010/078
|
||||||
|
frn: 24
|
||||||
|
rule: X
|
||||||
|
itemdesc: Aircraft Type
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 8
|
||||||
|
- itemno: I010/080
|
||||||
|
frn: 25
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Parking Position allocation
|
||||||
|
definition: Stand information for arrivals and/or de-icing zone/de-icing pad for departures that taxi for de-icing
|
||||||
|
format: fixed
|
||||||
|
octet: 4
|
||||||
|
structure:
|
||||||
|
- name: STAND
|
||||||
|
frombit: 32
|
||||||
|
tobit: 1
|
||||||
|
desc: Parking Position allocation
|
||||||
|
datatype: ascii
|
||||||
|
# - name: Char2
|
||||||
|
# frombit: 24
|
||||||
|
# tobit: 17
|
||||||
|
# desc: Char2
|
||||||
|
# datatype: string
|
||||||
|
# - name: Char3
|
||||||
|
# frombit: 16
|
||||||
|
# tobit: 9
|
||||||
|
# desc: Char3
|
||||||
|
# datatype: string
|
||||||
|
# - name: Char4
|
||||||
|
# frombit: 8
|
||||||
|
# tobit: 1
|
||||||
|
# desc: Char4
|
||||||
|
# datatype: string
|
||||||
|
- itemno: I010/034
|
||||||
|
frn: 26
|
||||||
|
rule: X
|
||||||
|
itemdesc: Control alert
|
||||||
|
definition: never present
|
||||||
|
format: variable
|
||||||
|
octet: 1
|
||||||
|
- itemno: I010/132
|
||||||
|
frn: 27
|
||||||
|
rule: X
|
||||||
|
itemdesc: Maneuver and Movement status
|
||||||
|
definition: never present
|
||||||
|
format: variable
|
||||||
|
octet: 1
|
||||||
|
- itemno: I010/046
|
||||||
|
frn: 28
|
||||||
|
rule: X
|
||||||
|
itemdesc: Topological position and TopoObject-Id
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 10
|
||||||
|
- itemno: I010/401
|
||||||
|
frn: 29
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Time To Threshold
|
||||||
|
definition: Time To Threshold
|
||||||
|
format: variable
|
||||||
|
octet: 0
|
||||||
|
- itemno: I010/401-1
|
||||||
|
frn: 2901
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Time To Threshold
|
||||||
|
definition: Time To Threshold
|
||||||
|
format: fixed
|
||||||
|
octet: 2
|
||||||
|
structure:
|
||||||
|
- name: SRC
|
||||||
|
frombit: 16
|
||||||
|
tobit: 16
|
||||||
|
desc: SRC
|
||||||
|
codes:
|
||||||
|
0: TTT source is ARTS / Approach.
|
||||||
|
1: TTT source is SDF.
|
||||||
|
- name: CST
|
||||||
|
frombit: 15
|
||||||
|
tobit: 15
|
||||||
|
desc: CST
|
||||||
|
codes:
|
||||||
|
0: approach system or computed by SDF basing on an updated.
|
||||||
|
1: extrapolated basing on computed.
|
||||||
|
- name: WRN
|
||||||
|
frombit: 14
|
||||||
|
tobit: 14
|
||||||
|
desc: WRN
|
||||||
|
codes:
|
||||||
|
0: Normal condition.
|
||||||
|
1: configurable threshold.
|
||||||
|
- name: TTT
|
||||||
|
frombit: 10
|
||||||
|
tobit: 2
|
||||||
|
desc: Seconds needed by aircraft to reach runway threshold.
|
||||||
|
unit: sec
|
||||||
|
max: 511
|
||||||
|
min: 0
|
||||||
|
- name: FX
|
||||||
|
frombit: 1
|
||||||
|
tobit: 1
|
||||||
|
codes:
|
||||||
|
0: No additional bytes are present.
|
||||||
|
1: Field extension.
|
||||||
|
- itemno: I010/401-2
|
||||||
|
frn: 2902
|
||||||
|
rule: optional
|
||||||
|
itemdesc: name of the runway
|
||||||
|
definition: name of the runway
|
||||||
|
format: fixed
|
||||||
|
octet: 3
|
||||||
|
structure:
|
||||||
|
- name: NU1
|
||||||
|
frombit: 24
|
||||||
|
tobit: 17
|
||||||
|
desc: First digit.
|
||||||
|
datatype: ascii
|
||||||
|
- name: NU2
|
||||||
|
frombit: 16
|
||||||
|
tobit: 9
|
||||||
|
desc: Second digit.
|
||||||
|
datatype: ascii
|
||||||
|
- name: LTR
|
||||||
|
frombit: 8
|
||||||
|
tobit: 1
|
||||||
|
desc: Letter.
|
||||||
|
datatype: ascii
|
||||||
|
- itemno: I010/400
|
||||||
|
frn: 35
|
||||||
|
rule: mandatory
|
||||||
|
itemdesc: Identification of fused Sensors
|
||||||
|
definition: Identification of fused Sensors
|
||||||
|
format: variable
|
||||||
|
octet: 1
|
||||||
|
- itemno: I010/400-1
|
||||||
|
frn: 3501
|
||||||
|
rule: mandatory
|
||||||
|
itemdesc: Identification of fused Sensors
|
||||||
|
definition: Identification of fused Sensors
|
||||||
|
format: fixed
|
||||||
|
octet: 1
|
||||||
|
structure:
|
||||||
|
- name: S7
|
||||||
|
frombit: 8
|
||||||
|
desc: sensor7
|
||||||
|
codes:
|
||||||
|
0: target not detected by sensor
|
||||||
|
1: target detected by sensor
|
||||||
|
- name: S6
|
||||||
|
frombit: 7
|
||||||
|
desc: sensor6
|
||||||
|
codes:
|
||||||
|
0: target not detected by sensor
|
||||||
|
1: target detected by sensor
|
||||||
|
- name: S5
|
||||||
|
frombit: 6
|
||||||
|
desc: sensor5
|
||||||
|
codes:
|
||||||
|
0: target not detected by sensor
|
||||||
|
1: target detected by sensor
|
||||||
|
- name: S4
|
||||||
|
frombit: 5
|
||||||
|
desc: sensor4
|
||||||
|
codes:
|
||||||
|
0: target not detected by sensor
|
||||||
|
1: target detected by sensor
|
||||||
|
- name: S3
|
||||||
|
frombit: 4
|
||||||
|
desc: sensor3, target detected by ADS-B
|
||||||
|
codes:
|
||||||
|
0: target not detected by sensor
|
||||||
|
1: target detected by sensor
|
||||||
|
- name: S2
|
||||||
|
frombit: 3
|
||||||
|
desc: sensor2, target detected by Apron Control Tower SMR
|
||||||
|
codes:
|
||||||
|
0: target not detected by sensor
|
||||||
|
1: target detected by sensor
|
||||||
|
- name: S1
|
||||||
|
frombit: 2
|
||||||
|
desc: sensor1, target detected by ATCT SMR
|
||||||
|
codes:
|
||||||
|
0: target not detected by sensor
|
||||||
|
1: target detected by sensor
|
||||||
|
- name: EXT
|
||||||
|
frombit: 8
|
||||||
|
desc: extension bit
|
||||||
|
- itemno: I010/081
|
||||||
|
frn: 36
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Runway (RWY)
|
||||||
|
definition: Allocated Runway found in flight plan is set in this item. This item can deviate from the Runway threshold set in item I010/401 Time to Threshold.
|
||||||
|
format: fixed
|
||||||
|
octet: 3
|
||||||
|
structure:
|
||||||
|
- name: RWY
|
||||||
|
frombit: 24
|
||||||
|
tobit: 1
|
||||||
|
desc: First ASCII character.
|
||||||
|
datatype: ascii
|
||||||
|
# - name: CHAR2
|
||||||
|
# frombit: 16
|
||||||
|
# tobit: 9
|
||||||
|
# desc: Second ASCII character.
|
||||||
|
# datatype: string
|
||||||
|
# - name: CHAR3
|
||||||
|
# frombit: 8
|
||||||
|
# tobit: 1
|
||||||
|
# desc: Third ASCII character.
|
||||||
|
# datatype: string
|
||||||
|
- itemno: I010/390
|
||||||
|
frn: 37
|
||||||
|
rule: X
|
||||||
|
itemdesc: Flight Plan Identifier (FPL-ID)
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 5
|
||||||
|
- itemno: I010/082
|
||||||
|
frn: 38
|
||||||
|
rule: X
|
||||||
|
itemdesc: Actual Start Up Given Time (SUG)
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 2
|
||||||
|
- itemno: I010/083
|
||||||
|
frn: 39
|
||||||
|
rule: X
|
||||||
|
itemdesc: Estimated/Actual Off-Block Time (EOFB/OFB)
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 2
|
||||||
|
- itemno: I010/084
|
||||||
|
frn: 40
|
||||||
|
rule: optional
|
||||||
|
itemdesc: Estimated Time of Arrival (ETA) or Estimated Time of Departure (ETD)
|
||||||
|
definition: The Estimated Time of Arrival (ETA) or Estimated Time of Departure (ETD)
|
||||||
|
format: fixed
|
||||||
|
octet: 2
|
||||||
|
structure:
|
||||||
|
- name: DAY
|
||||||
|
frombit: 16
|
||||||
|
tobit: 15
|
||||||
|
desc: DAY
|
||||||
|
codes:
|
||||||
|
0: This day
|
||||||
|
1: Last day
|
||||||
|
2: Next day
|
||||||
|
3: not used
|
||||||
|
- name: HOR
|
||||||
|
frombit: 14
|
||||||
|
tobit: 9
|
||||||
|
desc: Hours , from 0 to 23
|
||||||
|
- name: ArrDep
|
||||||
|
frombit: 8
|
||||||
|
tobit: 8
|
||||||
|
desc: Arrival/Departure Flag
|
||||||
|
codes:
|
||||||
|
0: Departure
|
||||||
|
1: Arrival
|
||||||
|
- name: Spare
|
||||||
|
frombit: 7
|
||||||
|
tobit: 7
|
||||||
|
desc: Spare
|
||||||
|
- name: MIN
|
||||||
|
frombit: 6
|
||||||
|
tobit: 1
|
||||||
|
desc: Minutes, from 0 to 59
|
||||||
|
- itemno: I010/085
|
||||||
|
frn: 41
|
||||||
|
rule: X
|
||||||
|
itemdesc: Estimated/Actual On-Block Time (EONB/ONB)
|
||||||
|
definition: never present
|
||||||
|
format: fixed
|
||||||
|
octet: 2
|
||||||
|
- itemno: I010/391
|
||||||
|
frn: 42
|
||||||
|
rule: mandatory
|
||||||
|
itemdesc: Flight Plan Info (FPL-INFO)
|
||||||
|
definition: gives the CWP the information which action is allowed to execute from the controller on the track.
|
||||||
|
format: fixed
|
||||||
|
octet: 1
|
||||||
|
structure:
|
||||||
|
- name: Drag&Drop
|
||||||
|
frombit: 8
|
||||||
|
tobit: 8
|
||||||
|
desc: Drag&Drop Assignment
|
||||||
|
codes:
|
||||||
|
0: Forbidden
|
||||||
|
1: Allowed
|
||||||
|
- name: Manual
|
||||||
|
frombit: 7
|
||||||
|
tobit: 7
|
||||||
|
desc: Manual Assignment
|
||||||
|
codes:
|
||||||
|
0: Forbidden
|
||||||
|
1: Allowed
|
||||||
|
- name: Deassignment
|
||||||
|
frombit: 6
|
||||||
|
tobit: 6
|
||||||
|
desc: Deassignment
|
||||||
|
codes:
|
||||||
|
0: Forbidden
|
||||||
|
1: Allowed
|
||||||
|
- name: Condition
|
||||||
|
frombit: 5
|
||||||
|
tobit: 4
|
||||||
|
desc: Condition
|
||||||
|
codes:
|
||||||
|
0: No flight plan is correlated with the track
|
||||||
|
1: Automatic identified track
|
||||||
|
2: Drag&drop identified track
|
||||||
|
3: Callsign manually assigned by operator
|
||||||
|
- name: Command
|
||||||
|
frombit: 3
|
||||||
|
tobit: 2
|
||||||
|
desc: Command
|
||||||
|
codes:
|
||||||
|
0: deassign
|
||||||
|
1: assign via automatic
|
||||||
|
2: assign via drag&drop
|
||||||
|
3: assign via manual
|
||||||
|
- name: SPA
|
||||||
|
frombit: 1
|
||||||
|
tobit: 1
|
||||||
|
desc: Spare Bit
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue