main
MonHun 2024-02-11 22:17:03 +09:00
commit b2856d00ee
51 changed files with 8394 additions and 0 deletions

33
.gitignore vendored 100644
View File

@ -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/

BIN
.mvn/wrapper/maven-wrapper.jar vendored 100644

Binary file not shown.

View File

@ -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

19
cfg/udpsocket.xml 100644
View File

@ -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.

188
mvnw.cmd vendored 100644
View File

@ -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%

122
pom.xml 100644
View File

@ -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>

View File

@ -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);
// }
// }
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View 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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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 ;
}
}

View File

@ -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();
}
}
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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 ======================");
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -0,0 +1,5 @@
package kr.gmtc.gw.comp.socket.event;
public abstract class EncryptEventListener implements IEncryptEventListener {
}

View File

@ -0,0 +1,5 @@
package kr.gmtc.gw.comp.socket.event;
public interface IEncryptEventListener {
public byte[] getByteArray(int id, byte[] data);
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -0,0 +1,5 @@
package kr.gmtc.gw.comp.socket.udp;
public abstract class UDPEventListener implements IUDPSocketHandler {
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,6 @@
package kr.gmtc.gw.comp.thread.handler;
@FunctionalInterface
public interface CustomThreadOnTerminate {
public void onTerminate();
}

View File

@ -0,0 +1,6 @@
package kr.gmtc.gw.comp.thread.handler;
@FunctionalInterface
public interface CustomThreadWork {
public void work() throws Exception;
}

View File

@ -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'"
}
]}

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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 twos 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