shjung před 1 rokem
rodič
revize
0576a3bc56
35 změnil soubory, kde provedl 805 přidání a 510 odebrání
  1. 9 5
      src/main/java/com/beanit/asn1bean/ber/types/BerAny.java
  2. 14 2
      src/main/java/com/beanit/enums/eAuthInfo.java
  3. 10 19
      src/main/java/com/beanit/enums/eObjectId.java
  4. 6 2
      src/main/java/com/beanit/its/Reject.java
  5. 8 2
      src/main/java/com/beanit/its/Subscription.java
  6. 56 108
      src/main/java/com/beanit/its/SubscriptionType.java
  7. 41 0
      src/main/java/com/beanit/its/SubscriptionTypePR.java
  8. 0 11
      src/main/java/com/beanit/utils/AsnIts.java
  9. 20 0
      src/main/java/com/beanit/utils/ItsAsn.java
  10. 10 1
      src/main/java/com/its/rota/server/config/ThreadPoolInitializer.java
  11. 152 0
      src/main/java/com/its/rota/server/dto/CenterDto.java
  12. 2 1
      src/main/java/com/its/rota/server/dto/NET.java
  13. 3 0
      src/main/java/com/its/rota/server/dto/NetState.java
  14. 22 0
      src/main/java/com/its/rota/server/dto/SendIncidentInfo.java
  15. 16 0
      src/main/java/com/its/rota/server/dto/SendTrafficInfo.java
  16. 4 0
      src/main/java/com/its/rota/server/entity/TbCenter.java
  17. 13 15
      src/main/java/com/its/rota/server/process/work/DataPacketWorker.java
  18. 8 8
      src/main/java/com/its/rota/server/repository/ApplicationRepository.java
  19. 12 12
      src/main/java/com/its/rota/server/scheduler/ApplicationScheduler.java
  20. 52 0
      src/main/java/com/its/rota/server/service/ItsRotaServerService.java
  21. 2 2
      src/main/java/com/its/rota/server/xnet/server/codec/ItsAsnServerDecoder.java
  22. 8 5
      src/main/java/com/its/rota/server/xnet/server/codec/ItsAsnServerEncoder.java
  23. 2 2
      src/main/java/com/its/rota/server/xnet/server/handler/ItsAsnServerPacketInboundHandler.java
  24. 97 0
      src/main/java/com/its/rota/server/xnet/server/process/request/AiAccept.java
  25. 8 17
      src/main/java/com/its/rota/server/xnet/server/process/request/AiInitialize.java
  26. 59 0
      src/main/java/com/its/rota/server/xnet/server/process/request/AiReject.java
  27. 11 18
      src/main/java/com/its/rota/server/xnet/server/process/request/AiTerminate.java
  28. 17 117
      src/main/java/com/its/rota/server/xnet/server/process/response/AcceptResponse.java
  29. 9 20
      src/main/java/com/its/rota/server/xnet/server/process/response/FredResponse.java
  30. 6 16
      src/main/java/com/its/rota/server/xnet/server/process/response/LoginResponse.java
  31. 19 25
      src/main/java/com/its/rota/server/xnet/server/process/response/LogoutResponse.java
  32. 93 81
      src/main/java/com/its/rota/server/xnet/server/process/response/SubscriptionResponse.java
  33. 13 18
      src/main/java/com/its/rota/server/xnet/server/process/response/TerminateResponse.java
  34. 2 2
      src/main/java/com/its/rota/server/xnet/server/process/service/impl/SubscriptionRegisterService.java
  35. 1 1
      src/main/java/com/its/rota/server/xnet/server/process/service/impl/SubscriptionSingleService.java

+ 9 - 5
src/main/java/com/beanit/asn1bean/ber/types/BerAny.java

@@ -67,12 +67,16 @@ public class BerAny implements Serializable, BerType {
 
     value = new byte[tagLength + lengthLength + lengthField.val];
 
-    Util.readFully(is, value, tagLength + lengthLength, lengthField.val);
-    ReverseByteArrayOutputStream os =
-        new ReverseByteArrayOutputStream(value, tagLength + lengthLength - 1);
-    BerLength.encodeLength(os, lengthField.val);
-    tag.encode(os);
+    try {
+      Util.readFully(is, value, tagLength + lengthLength, lengthField.val);
+      ReverseByteArrayOutputStream os =
+              new ReverseByteArrayOutputStream(value, tagLength + lengthLength - 1);
+      BerLength.encodeLength(os, lengthField.val);
+      tag.encode(os);
+    }
+    catch(Exception e) {
 
+    }
     return decodedLength;
   }
 

+ 14 - 2
src/main/java/com/beanit/enums/eAuthInfo.java

@@ -18,8 +18,20 @@ public enum eAuthInfo {
     AI_TransferDone((byte)0x07, "AI_TransferDone"),       /* 클라이언트가 요청한 정보를 파일형태로 제공하기 위한 데이터 패킷 */
     AI_Accept      ((byte)0x08, "AI_Accept"),             /* 클라이언트의 요청에 대한 수용 */
     AI_Reject      ((byte)0x09, "AI_Reject"),             /* 클라이언트의 요청에 대한 거부 */
-    AI_NonCryptObu ((byte)0x21, "AI_NonCryptObu"),
-    AI_Multimedia  ((byte)0x22, "AI_Multimedia");
+
+    /*
+    AI_Publication 0x20~0x40,              클라이언트가 요청한 정보를 제공하기 위한 데이터 패킷
+    */
+    AI_CurrentLinkState     ((byte)0x21, "AI_CurrentLinkState"),        /* 교통소통정보 */
+    AI_EventIdentity        ((byte)0x22, "AI_EventIdentity"),           /* 교통통제정보 */
+    AI_IncidentIdentity     ((byte)0x23, "AI_IncidentIdentity"),        /* 돌발상황발생정보 */
+    AI_IncidentConditions   ((byte)0x24, "AI_IncidentConditions"),      /* 돌발상황정보 */
+    AI_RoadwaySurfaceStatus ((byte)0x25, "AI_RoadwaySurfaceStatus"),    /* 도로상태정보 */
+    AI_WeatherInformation   ((byte)0x26, "AI_WeatherInformation"),      /* 기상정보 */
+    AI_LinkRoadwayGeometry  ((byte)0x27, "AI_LinkRoadwayGeometry"),     /* 도로관리정보 */
+    AI_ProbeVehicleDetection((byte)0x28, "AI_ProbeVehicleDetection"),   /* 프로브정보 */
+    AI_DetectorCollection   ((byte)0x29, "AI_DetectorCollection");      /* 차량검지정보 */
+
 
     @Getter
     private final byte value;

+ 10 - 19
src/main/java/com/beanit/enums/eObjectId.java

@@ -5,25 +5,16 @@ import java.util.Map;
 
 public enum eObjectId {
 
-    OBJ_CurrentLinkStateRoadSide           (401, "OBJ_CurrentLinkStateRoadSide"),             /* 제공, 교통소통정보 */
-    OBJ_EventIdentityRoadSide              (402, "OBJ_EventIdentityRoadSide"),                /* 제공, 교통통제정보 */
-    OBJ_IncidentConditionsRoadSide         (403, "OBJ_IncidentConditionsRoadSide"),           /* 제공, 돌발상황정보 */
-    OBJ_RoadwayConditionsRoadSide          (404, "OBJ_RoadwayConditionsRoadSide"),            /* 제공, 도로상태정보 */
-    OBJ_WeatherInformationRoadSide         (405, "OBJ_WeatherInformationRoadSide"),           /* 제공, 기상정보 */
-    OBJ_ProbeVehicleDetectionRoadSide      (406, "OBJ_ProbeVehicleDetectionRoadSide"),        /* 수집, 프로브정보 */
-    OBJ_ControlDevice                      (407, "OBJ_ControlDevice"),                        /* 제공, 제어정보 */
-    OBJ_MultiMediaData                     (501, "OBJ_MultiMediaData"),                       /* 제공, 멀티미디어 데이터 */
-    OBJ_OBUBasicInfo                       (801, "OBJ_OBUBasicInfo"),                         /* 수집, OBU 기본정보 */
-    OBJ_RecentETCOBUTransactionInfo        (802, "OBJ_RecentETCOBUTransactionInfo"),          /* 수집, 최근 ETC OBU 트랜잭션 정보*/
-    OBJ_TrafficInfoOBUBasicInfo            (803, "OBJ_TrafficInfoOBUBasicInfo"),              /* 수집, OBU 기본정보 */
-    OBJ_TrafficInfoDSRCCurrentSpotState    (804, "OBJ_TrafficInfoDSRCCurrentSpotState"),      /* 수집, 가상지점 수집정보 */
-    OBJ_TrafficInfoRecentOBUTransactionInfo(805, "OBJ_TrafficInfoRecentOBUTransactionInfo"),  /* 수집, 최근 OBU 트랜잭션 정보 */
-    OBJ_TrafficInfoDSRCSpotStateReq        (806, "OBJ_TrafficInfoDSRCSpotStateReq"),          /* 수집, 가상수집지점 요청정보 */
-    OBJ_TrafficInfoETCTransactionInfo      (807, "OBJ_TrafficInfoETCTransactionInfo"),        /* 수집, 최근 ETC 트랜잭션 정보 */
-    OBJ_OBUGatherInfo                      (808, "OBJ_OBUGatherInfo"),                        /* 수집, OBU 수집정보 */
-    OBJ_DSRCIndividualCurrentSpotState     (809, "OBJ_DSRCIndividualCurrentSpotState"),       /* 수집, 개별단말수집지점 정보 */
-    OBJ_DSRCRecentETCOBUTransactionInfo    (810, "OBJ_DSRCRecentETCOBUTransactionInfo"),      /* 수집, 최근 ETC OBU 트랜잭션 정보 */
-    OBJ_DSRCRecentOBUTransactionInfo       (811, "OBJ_DSRCRecentOBUTransactionInfo");         /* 수집, 최근 OBU 트랜잭션 수집정보 */
+
+    OBJ_CurrentLinkState      (111, "OBJ_CurrentLinkState"),             /* 교통소통정보 */
+    OBJ_EventIdentity         (112, "OBJ_EventIdentity"),                /* 교통통제정보 */
+    OBJ_IncidentIdentity      (113, "OBJ_IncidentIdentity"),           /* 돌발상황발생정보 */
+    OBJ_IncidentConditions    (114, "OBJ_IncidentConditions"),            /* 돌발상황정보 */
+    OBJ_RoadwaySurfaceStatus  (115, "OBJ_RoadwaySurfaceStatus"),           /* 도로상태정보 */
+    OBJ_WeatherInformation    (116, "OBJ_WeatherInformation"),        /* 기상정보 */
+    OBJ_LinkRoadwayGeometry   (117, "OBJ_LinkRoadwayGeometry"),        /* 도로관리정보 */
+    OBJ_ProbeVehicleDetection (118, "OBJ_ProbeVehicleDetection"),                        /* 도로관리정보 */
+    OBJ_DetectorCollection    (119, "OBJ_DetectorCollection");         /* 수집, 최근 OBU 트랜잭션 수집정보 */
 
     private final int value;
     private final String string;

+ 6 - 2
src/main/java/com/beanit/its/Reject.java

@@ -79,7 +79,9 @@ public class Reject implements BerType, Serializable {
 		int sublength;
 
 		if (datexRejectAlternateRequest != null) {
-			codeLength += datexRejectAlternateRequest.encode(reverseOS, false);
+			sublength = datexRejectAlternateRequest.encode(reverseOS);
+			codeLength += sublength;
+			codeLength += BerLength.encodeLength(reverseOS, sublength);
 			// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
 			reverseOS.write(0xA2);
 			codeLength += 1;
@@ -149,8 +151,10 @@ public class Reject implements BerType, Serializable {
 		}
 		
 		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			vByteCount += length.decode(is);
 			datexRejectAlternateRequest = new AlternateRequest();
-			vByteCount += datexRejectAlternateRequest.decode(is, false);
+			vByteCount += datexRejectAlternateRequest.decode(is, null);
+			vByteCount += length.readEocIfIndefinite(is);
 			if (lengthVal >= 0 && vByteCount == lengthVal) {
 				return tlByteCount + vByteCount;
 			}

+ 8 - 2
src/main/java/com/beanit/its/Subscription.java

@@ -67,7 +67,11 @@ public class Subscription implements BerType, Serializable {
 		}
 
 		int codeLength = 0;
-		codeLength += datexSubscribeType.encode(reverseOS, false);
+		int sublength;
+
+		sublength = datexSubscribeType.encode(reverseOS);
+		codeLength += sublength;
+		codeLength += BerLength.encodeLength(reverseOS, sublength);
 		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
 		reverseOS.write(0xA1);
 		codeLength += 1;
@@ -115,8 +119,10 @@ public class Subscription implements BerType, Serializable {
 		}
 		
 		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			vByteCount += length.decode(is);
 			datexSubscribeType = new SubscriptionType();
-			vByteCount += datexSubscribeType.decode(is, false);
+			vByteCount += datexSubscribeType.decode(is, null);
+			vByteCount += length.readEocIfIndefinite(is);
 			if (lengthVal >= 0 && vByteCount == lengthVal) {
 				return tlByteCount + vByteCount;
 			}

+ 56 - 108
src/main/java/com/beanit/its/SubscriptionType.java

@@ -23,11 +23,9 @@ public class SubscriptionType implements BerType, Serializable {
 
 	private static final long serialVersionUID = 1L;
 
-	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
-
 	private byte[] code = null;
-	private SubscriptionData present = null;
-	private SubscriptionTypeU choice = null;
+	private SubscriptionData subscription = null;
+	private BerEnum datexSubscribeCancelReasonCd = null;
 	
 	public SubscriptionType() {
 	}
@@ -36,117 +34,85 @@ public class SubscriptionType implements BerType, Serializable {
 		this.code = code;
 	}
 
-	public void setPresent(SubscriptionData present) {
-		this.present = present;
+	public void setSubscription(SubscriptionData subscription) {
+		this.subscription = subscription;
 	}
 
-	public SubscriptionData getPresent() {
-		return present;
+	public SubscriptionData getSubscription() {
+		return subscription;
 	}
 
-	public void setChoice(SubscriptionTypeU choice) {
-		this.choice = choice;
+	public void setDatexSubscribeCancelReasonCd(BerEnum datexSubscribeCancelReasonCd) {
+		this.datexSubscribeCancelReasonCd = datexSubscribeCancelReasonCd;
 	}
 
-	public SubscriptionTypeU getChoice() {
-		return choice;
+	public BerEnum getDatexSubscribeCancelReasonCd() {
+		return datexSubscribeCancelReasonCd;
 	}
 
 	@Override public int encode(OutputStream reverseOS) throws IOException {
-		return encode(reverseOS, true);
-	}
-
-	public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
 
 		if (code != null) {
 			reverseOS.write(code);
-			if (withTag) {
-				return tag.encode(reverseOS) + code.length;
-			}
 			return code.length;
 		}
 
 		int codeLength = 0;
-		int sublength;
-
-		sublength = choice.encode(reverseOS);
-		codeLength += sublength;
-		codeLength += BerLength.encodeLength(reverseOS, sublength);
-		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
-		reverseOS.write(0xA1);
-		codeLength += 1;
-		
-		codeLength += present.encode(reverseOS, false);
-		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
-		reverseOS.write(0xA0);
-		codeLength += 1;
+		if (datexSubscribeCancelReasonCd != null) {
+			codeLength += datexSubscribeCancelReasonCd.encode(reverseOS, false);
+			// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+			reverseOS.write(0x81);
+			codeLength += 1;
+			return codeLength;
+		}
 		
-		codeLength += BerLength.encodeLength(reverseOS, codeLength);
-
-		if (withTag) {
-			codeLength += tag.encode(reverseOS);
+		if (subscription != null) {
+			codeLength += subscription.encode(reverseOS, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+			reverseOS.write(0xA0);
+			codeLength += 1;
+			return codeLength;
 		}
-
-		return codeLength;
-
+		
+		throw new IOException("Error encoding CHOICE: No element of CHOICE was selected.");
 	}
 
 	@Override public int decode(InputStream is) throws IOException {
-		return decode(is, true);
+		return decode(is, null);
 	}
 
-	public int decode(InputStream is, boolean withTag) throws IOException {
-		int tlByteCount = 0;
-		int vByteCount = 0;
-		BerTag berTag = new BerTag();
+	public int decode(InputStream is, BerTag berTag) throws IOException {
 
-		if (withTag) {
-			tlByteCount += tag.decodeAndCheck(is);
-		}
+		int tlvByteCount = 0;
+		boolean tagWasPassed = (berTag != null);
 
-		BerLength length = new BerLength();
-		tlByteCount += length.decode(is);
-		int lengthVal = length.val;
-		vByteCount += berTag.decode(is);
+		if (berTag == null) {
+			berTag = new BerTag();
+			tlvByteCount += berTag.decode(is);
+		}
 
 		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
-			present = new SubscriptionData();
-			vByteCount += present.decode(is, false);
-			vByteCount += berTag.decode(is);
-		}
-		else {
-			throw new IOException("Tag does not match mandatory sequence component.");
-		}
-		
-		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
-			vByteCount += length.decode(is);
-			choice = new SubscriptionTypeU();
-			vByteCount += choice.decode(is, null);
-			vByteCount += length.readEocIfIndefinite(is);
-			if (lengthVal >= 0 && vByteCount == lengthVal) {
-				return tlByteCount + vByteCount;
-			}
-			vByteCount += berTag.decode(is);
+			subscription = new SubscriptionData();
+			tlvByteCount += subscription.decode(is, false);
+			return tlvByteCount;
 		}
-		else {
-			throw new IOException("Tag does not match mandatory sequence component.");
-		}
-		
-		if (lengthVal < 0) {
-			if (!berTag.equals(0, 0, 0)) {
-				throw new IOException("Decoded sequence has wrong end of contents octets");
-			}
-			vByteCount += BerLength.readEocByte(is);
-			return tlByteCount + vByteCount;
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			datexSubscribeCancelReasonCd = new BerEnum();
+			tlvByteCount += datexSubscribeCancelReasonCd.decode(is, false);
+			return tlvByteCount;
 		}
 
-		throw new IOException("Unexpected end of sequence, length tag: " + lengthVal + ", bytes decoded: " + vByteCount);
+		if (tagWasPassed) {
+			return 0;
+		}
 
+		throw new IOException("Error decoding CHOICE: Tag " + berTag + " matched to no item.");
 	}
 
 	public void encodeAndSave(int encodingSizeGuess) throws IOException {
 		ReverseByteArrayOutputStream reverseOS = new ReverseByteArrayOutputStream(encodingSizeGuess);
-		encode(reverseOS, false);
+		encode(reverseOS);
 		code = reverseOS.getArray();
 	}
 
@@ -158,36 +124,18 @@ public class SubscriptionType implements BerType, Serializable {
 
 	public void appendAsString(StringBuilder sb, int indentLevel) {
 
-		sb.append("{");
-		sb.append("\n");
-		for (int i = 0; i < indentLevel + 1; i++) {
-			sb.append("\t");
+		if (subscription != null) {
+			sb.append("subscription: ");
+			subscription.appendAsString(sb, indentLevel + 1);
+			return;
 		}
-		if (present != null) {
-			sb.append("present: ");
-			present.appendAsString(sb, indentLevel + 1);
-		}
-		else {
-			sb.append("present: <empty-required-field>");
-		}
-		
-		sb.append(",\n");
-		for (int i = 0; i < indentLevel + 1; i++) {
-			sb.append("\t");
-		}
-		if (choice != null) {
-			sb.append("choice: ");
-			choice.appendAsString(sb, indentLevel + 1);
-		}
-		else {
-			sb.append("choice: <empty-required-field>");
-		}
-		
-		sb.append("\n");
-		for (int i = 0; i < indentLevel; i++) {
-			sb.append("\t");
+
+		if (datexSubscribeCancelReasonCd != null) {
+			sb.append("datexSubscribeCancelReasonCd: ").append(datexSubscribeCancelReasonCd);
+			return;
 		}
-		sb.append("}");
+
+		sb.append("<none>");
 	}
 
 }

+ 41 - 0
src/main/java/com/beanit/its/SubscriptionTypePR.java

@@ -0,0 +1,41 @@
+/*
+ * This class file was automatically generated by ASN1bean v1.12.0 (http://www.beanit.com)
+ */
+
+package com.beanit.its;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import com.beanit.asn1bean.ber.*;
+import com.beanit.asn1bean.ber.types.*;
+import com.beanit.asn1bean.ber.types.string.*;
+
+
+public class SubscriptionTypePR extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public SubscriptionTypePR() {
+	}
+
+	public SubscriptionTypePR(byte[] code) {
+		super(code);
+	}
+
+	public SubscriptionTypePR(BigInteger value) {
+		super(value);
+	}
+
+	public SubscriptionTypePR(long value) {
+		super(value);
+	}
+
+}

+ 0 - 11
src/main/java/com/beanit/utils/AsnIts.java

@@ -1,11 +0,0 @@
-package com.beanit.utils;
-
-public class AsnIts {
-
-    public static final int ITS_ASN_PACKET_MAX_SIZE = 65535;
-    public static final int ITS_ASN_PACKET_MIN_SIZE = 8;
-    public static final int DATEX_VERSION_NUMBER_VERSION1 = 1;
-
-    public static final int SERVER_MAX_RETRY_COUNT = 3;
-
-}

+ 20 - 0
src/main/java/com/beanit/utils/ItsAsn.java

@@ -0,0 +1,20 @@
+package com.beanit.utils;
+
+public class ItsAsn {
+
+    public static final int ITS_ASN_PACKET_MAX_SIZE = 65535;
+    public static final int ITS_ASN_PACKET_MIN_SIZE = 8;
+    public static final int DATEX_VERSION_NUMBER_VERSION1 = 1;
+
+    public static final int SERVER_MAX_RETRY_COUNT = 3;
+
+    public static final int DATEX_MAX_STATE_COUNT = 1000;   /* max current link state count */
+    public static final int DATEX_MAX_EVENT_COUNT = 32;     /* max event identity count */
+    public static final int DATEX_MAX_INC_COUNT = 32;       /* max incident identity count */
+    public static final int DATEX_MAX_CON_COUNT = 32;       /* max incident conditions count */
+
+    public static final String DATEX_LINK_TEXT = "0000000000";
+    public static final String DATEX_NODE_TEXT = "0000000000";
+    public static final String DATEX_DEFAULT_TEXT = " ";
+
+}

+ 10 - 1
src/main/java/com/its/rota/server/config/ThreadPoolInitializer.java

@@ -36,7 +36,7 @@ public class ThreadPoolInitializer extends AsyncConfigurerSupport {
     public ThreadPoolTaskExecutor getDefaultExecutor(int poolSize) {
         ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
         threadPoolTaskExecutor.setCorePoolSize(poolSize);              // 인스턴스 되면서 기본적으로 띄울 스레드 개수.
-        // 아무작업이 없어도 corePoolSize 만큼 스레드가 생성
+        // 아무 작업이 없어도 corePoolSize 만큼 스레드가 생성
         threadPoolTaskExecutor.setMaxPoolSize(poolSize*2);   // 풀 최대개수, Queue Capacity 까지 꽉차는 경우 maxPoolSize 만큼 넓혀감
         threadPoolTaskExecutor.setQueueCapacity(1000);          // 스레드 대기큐, Queue Capacity 가 꽉차면 스레드가 추가로 생성됨. Async 처리시 Queue Size
         // (설정하지 않으면 Integer.MAX 이기 때문에 성능에 문제가 발생함)
@@ -59,4 +59,13 @@ public class ThreadPoolInitializer extends AsyncConfigurerSupport {
         return threadPoolTaskExecutor;
     }
 
+    @Bean(name="jobDataExecutor")
+    public Executor getJobDataExecutor() {
+        int workers = Math.max(8, Runtime.getRuntime().availableProcessors());
+        ThreadPoolTaskExecutor threadPoolTaskExecutor = getDefaultExecutor(workers*2);
+        threadPoolTaskExecutor.setThreadNamePrefix("data-pool-");
+        threadPoolTaskExecutor.initialize();
+        return threadPoolTaskExecutor;
+    }
+
 }

+ 152 - 0
src/main/java/com/its/rota/server/dto/CenterDto.java

@@ -1,13 +1,25 @@
 package com.its.rota.server.dto;
 
+import com.beanit.asn1bean.ber.ReverseByteArrayOutputStream;
+import com.beanit.asn1bean.ber.types.*;
+import com.beanit.asn1bean.ber.types.string.BerUTF8String;
+import com.beanit.enums.eAuthInfo;
+import com.beanit.its.*;
+import com.beanit.utils.ItsAsn;
 import com.beanit.utils.ItsAsnSequence;
+import com.its.rota.server.entity.TbSndIncident;
+import com.its.rota.server.repository.ApplicationRepository;
+import io.netty.channel.ChannelFuture;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
 
 import java.io.Serializable;
 
+@Slf4j
 @Data
 @Builder
 @NoArgsConstructor
@@ -26,6 +38,9 @@ public class CenterDto implements Serializable {
     private int resTime;            /* 응답시간                      */
     private int datagramSize;       /* 데이터그램 크기               */
 
+    private SendTrafficInfo traffic;
+    private SendIncidentInfo incident;
+
     private boolean commLogging;
     private ItsAsnSequence seq;
     private NetState netState;
@@ -44,9 +59,146 @@ public class CenterDto implements Serializable {
         this.commLogging = dto.isCommLogging();
         this.seq = new ItsAsnSequence();
         this.netState = new NetState();
+        this.traffic = new SendTrafficInfo();
+        this.incident = new SendIncidentInfo();
     }
     public String getLogKey() {
         return this.centerId;
     }
 
+    public boolean sendData(C2CAuthenticatedMessage c2c, String msg) {
+        if (this.netState.getChannel() == null) {
+            log.warn("SEND: [{}, {}]. Channel closed. {}.", this.centerId, this.ipAddress, msg);
+            return false;
+        }
+        ChannelFuture f = this.netState.getChannel().writeAndFlush(c2c);
+        f.awaitUninterruptibly();
+        if (f.isDone() || f.isSuccess()) {
+            log.info("SEND: [{}, {}]. Packet send Ok. {}.", this.centerId, this.ipAddress, msg);
+            return true;
+        }
+        log.error("SEND: [{}, {}]. Packet send Failed. {}. will be closed.", this.centerId, this.ipAddress, msg);
+        return false;
+    }
+
+    public boolean channelOpened() {
+        return this.netState.getChannel() != null && this.netState.getState() == NET.DATA_TRANS;
+    }
+
+    @Async("jobDataExecutor")
+    public void executeSendIncident() {
+        sendIncident();
+    }
+
+    public void sendIncident() {
+        try {
+            if (!channelOpened()) {
+                return;
+            }
+            if (this.incident.getSendIdx() > 0 && this.incident.getSendIdx() == this.incident.getIncidents().size()) {
+                // 모든 돌발 정보를 전송하였다.
+                return;
+            }
+
+            int start = this.incident.getSendIdx();
+            int end = Math.min(start + ItsAsn.DATEX_MAX_INC_COUNT, this.incident.getIncidents().size());
+            if (start == end) {
+                return;
+            }
+
+            IncidentConditionsList lists = new IncidentConditionsList();
+            for (int ii = start; ii < end; ii++) {
+                TbSndIncident data = this.incident.getIncidents().get(ii);
+                if (data.getNodeId() == null || data.getNodeId().isEmpty()) {
+                    data.setNodeId(ItsAsn.DATEX_NODE_TEXT);
+                }
+                if (data.getLinkId() == null || data.getLinkId().isEmpty()) {
+                    data.setLinkId(ItsAsn.DATEX_LINK_TEXT);
+                }
+                if (data.getContactOrganizationNameText() == null || data.getContactOrganizationNameText().isEmpty()) {
+                    data.setContactOrganizationNameText(ItsAsn.DATEX_DEFAULT_TEXT);
+                }
+                if (data.getDescriptionTypeIncidentOther() == null || data.getDescriptionTypeIncidentOther().isEmpty()) {
+                    data.setDescriptionTypeIncidentOther(ItsAsn.DATEX_DEFAULT_TEXT);
+                }
+                if (data.getIncidentVehiclesInvolvedOther() == null || data.getIncidentVehiclesInvolvedOther().isEmpty()) {
+                    data.setIncidentVehiclesInvolvedOther(ItsAsn.DATEX_DEFAULT_TEXT);
+                }
+                if (data.getIncidentStatusOther() == null || data.getIncidentStatusOther().isEmpty()) {
+                    data.setIncidentStatusOther(ItsAsn.DATEX_DEFAULT_TEXT);
+                }
+                if (data.getUpdateTypeOther() == null || data.getUpdateTypeOther().isEmpty()) {
+                    data.setUpdateTypeOther(ItsAsn.DATEX_DEFAULT_TEXT);
+                }
+
+                IncidentConditions cond = new IncidentConditions();
+
+                cond.setNodeNodeIdNumber(new BerUTF8String(data.getNodeId()));
+                cond.setLinkLinkIdNumber(new BerUTF8String(data.getLinkId()));
+                cond.setOrgnContactOrganizationNameText(new BerUTF8String(data.getContactOrganizationNameText()));
+                cond.setEvntDescriptionTypeIncidentCode(new BerEnum(data.getDescriptionTypeIncidentCode()));
+                cond.setEvntDescriptionTypeIncidentOther(new BerUTF8String(data.getDescriptionTypeIncidentOther()));
+
+                byte[] bitData = new byte[1];
+                bitData[0] = (byte) (data.getIncidentVehiclesInvolvedCode() & 0xFF);
+                cond.setEvntIncidentVehiclesInvolvedCode(new BerBitString(bitData, 8));
+
+                cond.setEvntIncidentVehiclesInvolvedOther(new BerUTF8String(data.getIncidentVehiclesInvolvedOther()));
+                cond.setEvntIncidentStatusCode(new BerEnum(data.getIncidentStatusCode()));
+                cond.setEvntIncidentStatusOther(new BerUTF8String(data.getIncidentStatusOther()));
+                cond.setEvntUpdateTypeCode(new BerEnum(data.getUpdateTypeCode()));
+                cond.setEvntUpdateTypeOther(new BerUTF8String(data.getUpdateTypeOther()));
+
+                lists.getIncidentConditions().add(cond);
+            }
+
+            if (lists.getIncidentConditions().isEmpty()) {
+                return;
+            }
+            EndApplicationMessage endMsg =  new EndApplicationMessage();
+            int[] messageId = {1, 0, 14827, 1, 1, 4};
+            ReverseByteArrayOutputStream msgBuff = new ReverseByteArrayOutputStream(ItsAsn.ITS_ASN_PACKET_MAX_SIZE);
+            lists.encode(msgBuff);
+            endMsg.setEndApplicationMessageId(new BerObjectIdentifier(messageId));
+            endMsg.setEndApplicationMessageMsg(new BerAny(msgBuff.getArray()));
+
+            byte[] auth = { eAuthInfo.AI_IncidentConditions.getValue() };
+            int packetNmbr = this.seq.nextValue();
+
+            PublicationType publicationType = new PublicationType();
+            publicationType.setDatexPublishData(endMsg);
+
+            PublicationData publicationData = new PublicationData();
+            publicationData.setDatexPublishSubscribeSerialNbr(new BerInteger(packetNmbr));  // 요청 serial nmbr
+            publicationData.setDatexPublishSerialNbr(new BerInteger(packetNmbr));           // 생성 serial nmbr
+            publicationData.setDatexPublishLatePublicationFlag(new BerBoolean(true));
+            publicationData.setDatexPublishType(publicationType);
+
+            PublishFormat.DatexPublishData publishData = new PublishFormat.DatexPublishData();
+            publishData.getPublicationData().add(publicationData);
+
+            PublishFormat publishFormat = new PublishFormat();
+            publishFormat.setDatexPublishData(publishData);
+
+            Publication publication = new Publication();
+            publication.setDatexPublishFormat(publishFormat);
+            publication.setDatexPublishGuaranteedBool(new BerBoolean(true));
+
+            C2CAuthenticatedMessage c2c = new C2CAuthenticatedMessage();
+            PDUs pdus = new PDUs();
+            pdus.setPublication(publication);
+            c2c.setDatexDataPacketNumber(new BerInteger(packetNmbr));
+            c2c.setDatexDataPacketPriorityNumber(new BerInteger(1));
+            c2c.setDatexAuthenticationInfoText(new BerOctetString(auth));
+            c2c.setOptions(ApplicationRepository.getHeaderOptions(this));
+            c2c.setPdu(pdus);
+
+            sendData(c2c, "AI_IncidentConditions");
+            this.incident.setSendIdx(end);
+        }
+        catch (Exception e) {
+            log.error("INCIDENT: [{}, {}]. Incident Data Send Exception. {}", this.centerId, this.ipAddress, e.getMessage());
+        }
+    }
+
 }

+ 2 - 1
src/main/java/com/its/rota/server/dto/NET.java

@@ -4,6 +4,7 @@ public class NET {
 
     public final static int CLOSED = 0; /* 종료된 상태 */
     public final static int LOGIN_WAIT = 1;      /* 최초 연결후 로그인 기다림 */
-    public final static int DATA_TRANS = 4;      /* data trans state */
+    public final static int DATA_TRANS = 2;      /* data trans state */
+    public final static int TERMINATE = 2;
 
 }

+ 3 - 0
src/main/java/com/its/rota/server/dto/NetState.java

@@ -63,6 +63,9 @@ public class NetState {
         this.disconnectTime = new Date();
         this.retryCount = 0;
     }
+    public void terminate() {
+        this.state = NET.TERMINATE;
+    }
     public boolean isActive() {
         return this.channel != null && this.channel.isActive();
     }

+ 22 - 0
src/main/java/com/its/rota/server/dto/SendIncidentInfo.java

@@ -0,0 +1,22 @@
+package com.its.rota.server.dto;
+
+import com.its.rota.server.entity.TbSndIncident;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class SendIncidentInfo {
+
+    private long baseTime;
+    private long sendTime;
+    private int sendIdx;
+    private List<TbSndIncident> incidents = new ArrayList<>();
+
+    public void init(long baseTime, List<TbSndIncident> incidents) {
+        this.baseTime = baseTime;
+        this.sendIdx = 0;
+        this.incidents = incidents;
+    }
+}

+ 16 - 0
src/main/java/com/its/rota/server/dto/SendTrafficInfo.java

@@ -0,0 +1,16 @@
+package com.its.rota.server.dto;
+
+import lombok.Data;
+
+@Data
+public class SendTrafficInfo {
+
+    private long baseTime;
+    private long sendTime;
+    private int sendIdx;
+
+    public void init(long baseTime) {
+        this.baseTime = baseTime;
+        this.sendIdx = 0;
+    }
+}

+ 4 - 0
src/main/java/com/its/rota/server/entity/TbCenter.java

@@ -3,6 +3,8 @@ package com.its.rota.server.entity;
 import com.beanit.utils.ItsAsnSequence;
 import com.its.rota.server.dto.CenterDto;
 import com.its.rota.server.dto.NetState;
+import com.its.rota.server.dto.SendIncidentInfo;
+import com.its.rota.server.dto.SendTrafficInfo;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
@@ -36,6 +38,8 @@ public class TbCenter {
                 .heartBeat(this.heartBeat)
                 .resTime(this.resTime)
                 .datagramSize(this.datagramSize)
+                .traffic(new SendTrafficInfo())
+                .incident(new SendIncidentInfo())
                 .commLogging(false)
                 .seq(new ItsAsnSequence())
                 .netState(new NetState())

+ 13 - 15
src/main/java/com/its/rota/server/process/work/DataPacketWorker.java

@@ -8,9 +8,7 @@ import com.its.rota.server.dto.RecvPacketDto;
 import com.its.rota.server.process.AbstractAppWorker;
 import com.its.rota.server.process.dbms.DbmsDataProcess;
 import com.its.rota.server.repository.ApplicationRepository;
-import com.its.rota.server.xnet.server.process.response.FredResponse;
-import com.its.rota.server.xnet.server.process.response.ItsAsnResponse;
-import com.its.rota.server.xnet.server.process.response.LoginResponse;
+import com.its.rota.server.xnet.server.process.response.*;
 import io.netty.channel.Channel;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
@@ -94,21 +92,21 @@ public class DataPacketWorker extends AbstractAppWorker implements Runnable {
                 case AI_FrED:
                     response = new FredResponse(center, c2c);
                     break;
-//                case AI_Terminate   :   //(0x04, "AI_Terminate"),          /* 연결을 종료하고자 할 때, 서버에서 클라이언트에 요청하는 데이터 패킷 */
-//                    response = new TerminateResponse(obj, ctx, c2c);
-//                    break;
-//                case AI_Logout      :   //(0x05, "AI_Logout"),             /* 접속을 종료하기 위한 클라이언트의 로그아웃 데이터 패킷 */
-//                    response = new LogoutResponse(obj, ctx, c2c);
-//                    break;
-//                case AI_Subscription:   //(0x06, "AI_Subscription"),       /* 클라이언트가 서버에 정보를 요청할 경우 송신하는 데이터 패킷 */
-//                    response = new SubscriptionResponse(obj, ctx, c2c);
-//                    break;
+                case AI_Terminate: // 연결을 종료하고자 할 때, 서버에서 클라이언트에 요청하는 데이터 패킷
+                    response = new TerminateResponse(center, c2c);
+                    break;
+                case AI_Logout: // 접속을 종료하기 위한 클라이언트의 로그아웃 데이터 패킷
+                    response = new LogoutResponse(center, c2c);
+                    break;
+                case AI_Subscription: // 클라이언트가 서버에 정보를 요청할 경우 송신하는 데이터 패킷
+                    response = new SubscriptionResponse(center, c2c);
+                    break;
 //                case AI_Publication :   //(0x07, "AI_Publication"),        /* 클라이언트가 요청한 정보를 제공하기 위한 데이터 패킷 - 요청에 대한 정보공개*/
 //                    response = new PublicationResponse(obj, ctx, c2c);
 //                    break;
-//                case AI_Accept      :   //(0x09, "AI_Accept"),             /* 클라이언트의 요청에 대한 수용 */
-//                    response = new AcceptResponse(obj, ctx, c2c);
-//                    break;
+                case AI_Accept      :   //(0x09, "AI_Accept"),             /* 클라이언트의 요청에 대한 수용 */
+                    response = new AcceptResponse(center, c2c);
+                    break;
 //                case AI_Reject      :   //(0x0A, "AI_Reject");             /* 클라이언트의 요청에 대한 거부 */
 //                    // 운영단말 명령에 대한 거부도 발생할 수 있으므로 운영단말로 결과를 전송한다.
 //                    response = new RejectResponse(obj, ctx, c2c);

+ 8 - 8
src/main/java/com/its/rota/server/repository/ApplicationRepository.java

@@ -9,6 +9,7 @@ import com.its.rota.server.dao.mapper.CenterMapper;
 import com.its.rota.server.dto.CenterDto;
 import com.its.rota.server.dto.NET;
 import com.its.rota.server.entity.TbCenter;
+import com.its.rota.server.entity.TbTrafficCenter;
 import com.its.rota.server.xnet.server.process.request.AiTerminate;
 import io.netty.channel.Channel;
 import io.netty.util.AttributeKey;
@@ -34,6 +35,7 @@ public class ApplicationRepository {
 
     public static final AttributeKey<CenterDto> CENTER_ATTRIBUTE_KEY = AttributeKey.valueOf("centerInfo");
     public static final CenterDto center = new CenterDto();
+    public static List<TbTrafficCenter> traffics = new ArrayList<>();
 
     private final HashMap<String, CenterDto> centerMap = new HashMap<>();
     private final HashMap<String, CenterDto> ipAddressMap = new HashMap<>();
@@ -42,16 +44,13 @@ public class ApplicationRepository {
     public static void closeChannel(CenterDto center, Channel channel) {
         try {
             if (center != null && center.getNetState().getState() > NET.LOGIN_WAIT) {
-                center.getNetState().setState(NET.CLOSED);
                 AiTerminate.run(center);
             }
-            channel.flush();
-//            ChannelFuture f = channel.disconnect().awaitUninterruptibly();  // channelInactive event fire
-//            if (!f.isDone() || !f.isSuccess()) {
-//                log.error("ItsAsnServerIdleStateConnectionHandler.disconnectChannel: {}, isDone: {}, isSuccess: {}", ipAddress, f.isDone(), f.isSuccess());
-//            }
-            channel.disconnect();
-            channel.close();
+            if (channel != null) {
+                channel.flush();
+                channel.disconnect();
+                channel.close();
+            }
         }
         catch (Exception e) {
             log.error("ApplicationRepository.closeChannel Exception: {}", e.getMessage());
@@ -85,6 +84,7 @@ public class ApplicationRepository {
 
         return hdrOpts;
     }
+
     @PostConstruct
     private void init() {
         log.info("AppRepositoryService.init: start.");

+ 12 - 12
src/main/java/com/its/rota/server/scheduler/ApplicationScheduler.java

@@ -43,10 +43,10 @@ public class ApplicationScheduler {
     @Scheduled(cron = "0 * * * * *")  // 1분 주기 작업 실행
     public void checkSendIncident() {
         Elapsed elapsed = new Elapsed();
-//        log.info("ApplicationScheduler.checkSendIncident: start.");
+        log.info("ApplicationScheduler.checkSendIncident: start.");
         try {
-            //this.itsRotaServerService.checkSendIncident();
-//            log.info("ApplicationScheduler.checkSendIncident: {}", Elapsed.elapsedTimeStr(elapsed.nanoSeconds()));
+            this.itsRotaServerService.checkSendIncident();
+            log.info("ApplicationScheduler.checkSendIncident: {}", Elapsed.elapsedTimeStr(elapsed.nanoSeconds()));
         }
         catch(Exception e) {
             log.error("ApplicationScheduler.checkSendIncident: Exception {}", e.getMessage());
@@ -56,15 +56,15 @@ public class ApplicationScheduler {
     @Async
     @Scheduled(cron = "0/10 * * * * *")  // 10초 주기 작업 실행
     public void checkSendTraffic() {
-//        Elapsed elapsed = new Elapsed();
-//        log.info("ApplicationScheduler.checkSendTraffic: start.");
-//        try {
-//            int result = this.itsRotaServerService.checkSendTraffic();
-//            log.info("ApplicationScheduler.checkSendTraffic: result: {}, {}", result, Elapsed.elapsedTimeStr(elapsed.nanoSeconds()));
-//        }
-//        catch(Exception e) {
-//            log.error("ApplicationScheduler.checkSendTraffic: Exception {}", e.getMessage());
-//        }
+        Elapsed elapsed = new Elapsed();
+        log.info("ApplicationScheduler.checkSendTraffic: start.");
+        try {
+            int result = this.itsRotaServerService.checkSendTraffic();
+            log.info("ApplicationScheduler.checkSendTraffic: result: {}, {}", result, Elapsed.elapsedTimeStr(elapsed.nanoSeconds()));
+        }
+        catch(Exception e) {
+            log.error("ApplicationScheduler.checkSendTraffic: Exception {}", e.getMessage());
+        }
     }
 
 }

+ 52 - 0
src/main/java/com/its/rota/server/service/ItsRotaServerService.java

@@ -47,6 +47,19 @@ public class ItsRotaServerService {
         log.error("ItsRotaServerService.destroy. system terminated.......");
     }
 
+    public void resetCenterTrafficSend() {
+        long baseTime = System.currentTimeMillis();
+        List<String> keySet = new ArrayList<>(this.repo.getCenterMap().keySet());
+        Collections.sort(keySet);
+        for (String key : keySet) {
+            CenterDto center = this.repo.getCenterMap().get(key);
+            if (center == null) {
+                continue;
+            }
+            center.getTraffic().init(baseTime);
+        }
+    }
+
     public int checkSendTraffic() {
         if (this.isRunning) {
             log.warn("ItsRotaServerService.checkSendTraffic: Already running");
@@ -62,10 +75,13 @@ public class ItsRotaServerService {
                 String trafficTime = result.get(0).getRegDate();
                 log.info("ItsRotaServerService.checkSendTraffic: checkTrafficTime: {}, currTrafficTime: {}.", this.checkTrafficTime, trafficTime);
                 if (!this.checkTrafficTime.equals(trafficTime)) {
+                    resetCenterTrafficSend();
                     elapsed1.reset();
                     List<TbTrafficCenter> traffics = this.mapper.selTrafficCenter();
                     log.info("ItsRotaServerService.selTrafficCenter: {} EA. {}", traffics.size(), Elapsed.elapsedTimeStr(elapsed1.nanoSeconds()));
                     this.checkTrafficTime = trafficTime;
+
+                    ApplicationRepository.traffics = traffics;
                 }
             }
         }
@@ -90,6 +106,7 @@ public class ItsRotaServerService {
             int deletes = this.incidentMapper.delCheckIncident();
             log.info("ItsRotaServerService.checkSendIncident: delCheckIncident {} EA. {}", deletes, Elapsed.elapsedTimeStr(elapsed1.nanoSeconds()));
 
+            long baseTime = System.currentTimeMillis();
             List<String> keySet = new ArrayList<>(this.repo.getCenterMap().keySet());
             Collections.sort(keySet);
             for (String key : keySet) {
@@ -97,6 +114,7 @@ public class ItsRotaServerService {
                 if (center == null) {
                     continue;
                 }
+
                 TbCheckIncident incident = TbCheckIncident.builder()
                         .fromCenterId(ApplicationRepository.center.getCenterId())
                         .toCenterId(center.getCenterId())
@@ -107,6 +125,40 @@ public class ItsRotaServerService {
                 log.info("ItsRotaServerService.checkSendIncident: insSndIncident {}, {} EA. {}", center.getCenterId(), inserts, Elapsed.elapsedTimeStr(elapsed1.nanoSeconds()));
                 // 지역센터에 전송할 돌발정보를 메모리에 저장하고 지역센터에 전송하여야 한다.
                 List<TbSndIncident> result = this.incidentMapper.selSndIncident(incident);
+                if ("L99".equals(center.getCenterId())) {
+                    TbSndIncident data = TbSndIncident.builder()
+                            .linkId("1111111111")
+                            .nodeId("1111111111")
+                            .contactOrganizationNameText("1111111111")
+                            .descriptionTypeIncidentCode(1)
+                            .descriptionTypeIncidentOther("1111111111")
+                            .incidentVehiclesInvolvedCode(1)
+                            .incidentVehiclesInvolvedOther("1111111111")
+                            .incidentStatusCode(1)
+                            .incidentStatusOther(" 127.787941624999 37.7560849154680")
+                            .updateTypeCode(1)
+                            .updateTypeOther("202408081639002024080812170020240808124700")
+                            .build();
+                    result.add(data);
+                    TbSndIncident data1 = TbSndIncident.builder()
+                            .linkId("2222222222")
+                            .nodeId("2222222222")
+                            .contactOrganizationNameText("2222222222")
+                            .descriptionTypeIncidentCode(2)
+                            .descriptionTypeIncidentOther("2222222222")
+                            .incidentVehiclesInvolvedCode(2)
+                            .incidentVehiclesInvolvedOther("2222222222")
+                            .incidentStatusCode(2)
+                            .incidentStatusOther(" 127.787941624999 37.7560849154680")
+                            .updateTypeCode(2)
+                            .updateTypeOther("202408081639002024080812170020240808124700")
+                            .build();
+                    result.add(data1);
+                }
+                center.getIncident().init(baseTime, result);
+                if (!result.isEmpty()) {
+                    center.executeSendIncident();
+                }
                 log.info("ItsRotaServerService.checkSendIncident: selSndIncident {}, {} EA. {}", center.getCenterId(), result.size(), Elapsed.elapsedTimeStr(elapsed1.nanoSeconds()));
             }
         }

+ 2 - 2
src/main/java/com/its/rota/server/xnet/server/codec/ItsAsnServerDecoder.java

@@ -3,7 +3,7 @@ package com.its.rota.server.xnet.server.codec;
 import com.beanit.asn1bean.ber.types.BerOctetString;
 import com.beanit.its.C2CAuthenticatedMessage;
 import com.beanit.its.DatexDataPacket;
-import com.beanit.utils.AsnIts;
+import com.beanit.utils.ItsAsn;
 import com.beanit.utils.ItsAsnCrc16;
 import com.its.app.common.utils.NettyUtils;
 import com.its.app.common.utils.SysUtils;
@@ -56,7 +56,7 @@ public class ItsAsnServerDecoder extends MessageToMessageDecoder<ByteBuf> {
 
         boolean isError = false;
         int pktLength;
-        while (readableBytes > AsnIts.ITS_ASN_PACKET_MIN_SIZE) {
+        while (readableBytes > ItsAsn.ITS_ASN_PACKET_MIN_SIZE) {
 
             byteBuf.markReaderIndex();
             byte[] inBytes = new byte[byteBuf.readableBytes()];

+ 8 - 5
src/main/java/com/its/rota/server/xnet/server/codec/ItsAsnServerEncoder.java

@@ -5,11 +5,12 @@ import com.beanit.asn1bean.ber.types.BerEnum;
 import com.beanit.asn1bean.ber.types.BerOctetString;
 import com.beanit.its.C2CAuthenticatedMessage;
 import com.beanit.its.DatexDataPacket;
-import com.beanit.utils.AsnIts;
+import com.beanit.utils.ItsAsn;
 import com.beanit.utils.ItsAsnCrc16;
 import com.its.app.common.utils.NettyUtils;
 import com.its.app.common.utils.SysUtils;
 import com.its.rota.server.dto.CenterDto;
+import com.its.rota.server.dto.NET;
 import com.its.rota.server.repository.ApplicationRepository;
 import io.netty.buffer.ByteBuf;
 import io.netty.channel.ChannelHandler;
@@ -46,12 +47,12 @@ public class ItsAsnServerEncoder extends MessageToByteEncoder<Object> {
 
         C2CAuthenticatedMessage c2c = (C2CAuthenticatedMessage)msg;
         try {
-            ReverseByteArrayOutputStream c2cBuff = new ReverseByteArrayOutputStream(AsnIts.ITS_ASN_PACKET_MAX_SIZE);
-            ReverseByteArrayOutputStream pktBuff = new ReverseByteArrayOutputStream(AsnIts.ITS_ASN_PACKET_MAX_SIZE);
+            ReverseByteArrayOutputStream c2cBuff = new ReverseByteArrayOutputStream(ItsAsn.ITS_ASN_PACKET_MAX_SIZE);
+            ReverseByteArrayOutputStream pktBuff = new ReverseByteArrayOutputStream(ItsAsn.ITS_ASN_PACKET_MAX_SIZE);
             int length = c2c.encode(c2cBuff);
             if (length > 0) {
                 DatexDataPacket dataPkt = new DatexDataPacket();
-                dataPkt.setDatexVersionNumber(new BerEnum(AsnIts.DATEX_VERSION_NUMBER_VERSION1));  // version == 1
+                dataPkt.setDatexVersionNumber(new BerEnum(ItsAsn.DATEX_VERSION_NUMBER_VERSION1));  // version == 1
                 dataPkt.setDatexData(new BerOctetString(c2cBuff.getArray()));
                 dataPkt.setDatexCrcNbr(new BerOctetString(ItsAsnCrc16.getCrc16ToByteArray(c2cBuff.getArray())));  // crc
 
@@ -71,7 +72,9 @@ public class ItsAsnServerEncoder extends MessageToByteEncoder<Object> {
         }
         catch (Exception e) {
             log.error("SEND: [{}, {}]. Exception Error: will be closed: {}.", center.getLogKey(), center.getIpAddress(), e.getMessage());
-            ApplicationRepository.closeChannel(center, ctx.channel());
+            if (center.getNetState().getState() != NET.TERMINATE) {
+                ApplicationRepository.closeChannel(center, ctx.channel());
+            }
         }
 
         MDC.remove(center.getLogKey());

+ 2 - 2
src/main/java/com/its/rota/server/xnet/server/handler/ItsAsnServerPacketInboundHandler.java

@@ -1,6 +1,6 @@
 package com.its.rota.server.xnet.server.handler;
 
-import com.beanit.utils.AsnIts;
+import com.beanit.utils.ItsAsn;
 import com.its.app.common.utils.NettyUtils;
 import com.its.rota.server.dto.CenterDto;
 import com.its.rota.server.dto.NET;
@@ -67,7 +67,7 @@ public class ItsAsnServerPacketInboundHandler extends SimpleChannelInboundHandle
 
                 if (center.getNetState().getState() <= NET.LOGIN_WAIT && (recvTimeout > (center.getResTime() * 1000L))) {
                     // 접속 후 로그인 처리가 되지 않은 경우
-                    if (center.getNetState().getRetryCount() >= AsnIts.SERVER_MAX_RETRY_COUNT) {
+                    if (center.getNetState().getRetryCount() >= ItsAsn.SERVER_MAX_RETRY_COUNT) {
                         log.error("IDLE: [{}, {}]. Login Timeout, {}, {} ms. Will be closed.", center.getLogKey(), center.getIpAddress(), recvTimeout, center.getResTime() * 1000L);
                         ApplicationRepository.closeChannel(center, ctx.channel());
                     }

+ 97 - 0
src/main/java/com/its/rota/server/xnet/server/process/request/AiAccept.java

@@ -0,0 +1,97 @@
+package com.its.rota.server.xnet.server.process.request;
+
+import com.beanit.asn1bean.ber.types.BerEnum;
+import com.beanit.asn1bean.ber.types.BerInteger;
+import com.beanit.asn1bean.ber.types.BerNull;
+import com.beanit.asn1bean.ber.types.BerOctetString;
+import com.beanit.enums.eAuthInfo;
+import com.beanit.enums.ePdusPr;
+import com.beanit.its.*;
+import com.beanit.utils.ItsAsnUtils;
+import com.its.rota.server.dto.CenterDto;
+import com.its.rota.server.repository.ApplicationRepository;
+
+public class AiAccept {
+
+    public static C2CAuthenticatedMessage makeMessage(CenterDto center, C2CAuthenticatedMessage c2c) {
+        C2CAuthenticatedMessage resC2c = null;
+        PDUs pdus = c2c.getPdu();
+        ePdusPr pdu = ItsAsnUtils.getPduChoice(pdus);
+
+        byte[] accept = { eAuthInfo.AI_Accept.getValue() };
+        PDUs resPdus = new PDUs();
+        Accept acpt = new Accept();
+        Accept.DatexAcceptType acptType = new Accept.DatexAcceptType();
+
+        switch(pdu) {
+            case PDUs_PR_login:
+                resC2c = new C2CAuthenticatedMessage();
+                Login login = pdus.getLogin();
+                acptType.setLogIn(login.getDatexLoginEncodingRulesId().getBerObjectIdentifier().get(0));
+                break;
+            case PDUs_PR_subscripiton:
+                resC2c = new C2CAuthenticatedMessage();
+                Subscription subscription = c2c.getPdu().getSubscription();
+                SubscriptionType subscriptionType = subscription.getDatexSubscribeType();
+                BerEnum cancelReasonCd = subscriptionType.getDatexSubscribeCancelReasonCd();
+                if (subscriptionType != null) {
+                    // Subscription
+                    SubscriptionData subscriptionData = subscriptionType.getSubscription();
+                    SubscriptionMode subscriptionMode = subscriptionData.getDatexSubscribeMode();
+                    BerNull single = subscriptionMode.getSingle();
+                    Registered eventDriven = subscriptionMode.getEventDriven();
+                    Registered periodic = subscriptionMode.getPeriodic();
+
+                    if (single != null) {
+                        acptType.setSingleSubscription(new BerNull());
+                    }
+                    else if (eventDriven != null) {
+                        Registered.Continuous cont = eventDriven.getContinuous();
+                        if (cont != null) {
+                            acptType.setRegisteredSubscription(cont.getDatexRegisteredUpdateDelayQty());
+                        }
+                        else {
+                            acptType.setRegisteredSubscription(subscription.getDatexSubscribeSerialNbr());
+                        }
+                    }
+                    else if (periodic != null) {
+                        Registered.Continuous cont = periodic.getContinuous();
+                        if (cont != null) {
+                            acptType.setRegisteredSubscription(cont.getDatexRegisteredUpdateDelayQty());
+                        }
+                        else {
+                            acptType.setRegisteredSubscription(subscription.getDatexSubscribeSerialNbr());
+                        }
+                    }
+                    else {
+                        return null;
+                    }
+                }
+                else if (cancelReasonCd != null) {
+                    // Cancel
+                    acptType.setRegisteredSubscription(subscription.getDatexSubscribeSerialNbr());
+                }
+                break;
+            case PDUs_PR_publication:
+                resC2c = new C2CAuthenticatedMessage();
+                BerNull berNull = new BerNull();
+                acptType.setPublication(berNull);
+                break;
+            default:
+                break;
+        }
+
+        if (resC2c != null) {
+            acpt.setDatexAcceptPacketNbr(c2c.getDatexDataPacketNumber());
+            acpt.setDatexAcceptType(acptType);
+            resPdus.setAccept(acpt);
+
+            resC2c.setDatexAuthenticationInfoText(new BerOctetString(accept));
+            resC2c.setDatexDataPacketNumber(new BerInteger(center.getSeq().nextValue()));
+            resC2c.setDatexDataPacketPriorityNumber(new BerInteger(0));
+            resC2c.setOptions(ApplicationRepository.getHeaderOptions(center));
+            resC2c.setPdu(resPdus);
+        }
+        return resC2c;
+    }
+}

+ 8 - 17
src/main/java/com/its/rota/server/xnet/server/process/request/AiInitialize.java

@@ -10,7 +10,6 @@ import com.beanit.its.Initiate;
 import com.beanit.its.PDUs;
 import com.its.rota.server.dto.CenterDto;
 import com.its.rota.server.repository.ApplicationRepository;
-import io.netty.channel.ChannelFuture;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
 
@@ -18,7 +17,7 @@ import org.slf4j.MDC;
 public class AiInitialize {
 
     public static boolean run(CenterDto center) {
-        boolean result = true;
+        boolean result;
         try {
             MDC.put("id", center.getLogKey());
             log.info("AiInitialize.run: [{}, {}].", center.getLogKey(), center.getIpAddress());
@@ -32,22 +31,14 @@ public class AiInitialize {
 
             HeaderOptions hdrOpts = ApplicationRepository.getHeaderOptions(center);
 
-            C2CAuthenticatedMessage resC2c = new C2CAuthenticatedMessage();
-            resC2c.setDatexAuthenticationInfoText(new BerOctetString(auth));
-            resC2c.setDatexDataPacketNumber(new BerInteger(center.getSeq().nextValue()));
-            resC2c.setDatexDataPacketPriorityNumber(new BerInteger(1));
-            resC2c.setOptions(hdrOpts);
-            resC2c.setPdu(pdUs);
+            C2CAuthenticatedMessage c2c = new C2CAuthenticatedMessage();
+            c2c.setDatexAuthenticationInfoText(new BerOctetString(auth));
+            c2c.setDatexDataPacketNumber(new BerInteger(center.getSeq().nextValue()));
+            c2c.setDatexDataPacketPriorityNumber(new BerInteger(1));
+            c2c.setOptions(hdrOpts);
+            c2c.setPdu(pdUs);
 
-            ChannelFuture f = center.getNetState().getChannel().writeAndFlush(resC2c);
-            f.awaitUninterruptibly();
-            if (f.isDone() || f.isSuccess()) {
-                log.info("AiInitialize.run: [{}, {}]. Packet send OK.", center.getLogKey(), center.getIpAddress());
-            }
-            else {
-                log.error("AiInitialize.run: [{}, {}]. Packet send Failed. will be closed.", center.getLogKey(), center.getIpAddress());
-                result = false;
-            }
+            result = center.sendData(c2c, "AI_Initiate");
         }
         catch (Exception e) {
             log.error("AiInitialize.run: [{}, {}]. Packet send Exception. will be closed. {}", center.getLogKey(), center.getIpAddress(), e.getMessage());

+ 59 - 0
src/main/java/com/its/rota/server/xnet/server/process/request/AiReject.java

@@ -0,0 +1,59 @@
+package com.its.rota.server.xnet.server.process.request;
+
+import com.beanit.asn1bean.ber.types.BerEnum;
+import com.beanit.asn1bean.ber.types.BerInteger;
+import com.beanit.asn1bean.ber.types.BerOctetString;
+import com.beanit.enums.eAuthInfo;
+import com.beanit.enums.ePdusPr;
+import com.beanit.its.C2CAuthenticatedMessage;
+import com.beanit.its.PDUs;
+import com.beanit.its.Reject;
+import com.beanit.its.RejectType;
+import com.beanit.utils.ItsAsnUtils;
+import com.its.rota.server.dto.CenterDto;
+import com.its.rota.server.repository.ApplicationRepository;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class AiReject {
+
+    public static C2CAuthenticatedMessage makeMessage(CenterDto center, C2CAuthenticatedMessage c2c, int rejectType) {
+        C2CAuthenticatedMessage resC2c = null;
+        ePdusPr pdu = ItsAsnUtils.getPduChoice(c2c.getPdu());
+
+        byte[] reject = { eAuthInfo.AI_Reject.getValue() };
+        PDUs resPdus = new PDUs();
+        Reject rjt = new Reject();
+        RejectType rjtType = new RejectType();
+
+        switch(pdu) {
+            case PDUs_PR_login:
+                resC2c = new C2CAuthenticatedMessage();
+                rjtType.setDatexRejectLoginCd(new BerEnum(rejectType));
+                break;
+            case PDUs_PR_subscripiton:
+                resC2c = new C2CAuthenticatedMessage();
+                rjtType.setDatexRejectSubscriptionCd(new BerEnum(rejectType));
+                break;
+            case PDUs_PR_publication:
+                resC2c = new C2CAuthenticatedMessage();
+                rjtType.setDatexRejectPublicationCd(new BerEnum(rejectType));
+                break;
+            default:
+                break;
+        }
+
+        if (resC2c != null) {
+            rjt.setDatexRejectPacketNbr(c2c.getDatexDataPacketNumber());
+            rjt.setDatexRejectType(rjtType);
+            resPdus.setReject(rjt);
+
+            resC2c.setDatexAuthenticationInfoText(new BerOctetString(reject));
+            resC2c.setDatexDataPacketNumber(new BerInteger(center.getSeq().nextValue()));
+            resC2c.setDatexDataPacketPriorityNumber(new BerInteger(1));
+            resC2c.setOptions(ApplicationRepository.getHeaderOptions(center));
+            resC2c.setPdu(resPdus);
+        }
+        return resC2c;
+    }
+}

+ 11 - 18
src/main/java/com/its/rota/server/xnet/server/process/request/AiTerminate.java

@@ -3,13 +3,13 @@ package com.its.rota.server.xnet.server.process.request;
 import com.beanit.asn1bean.ber.types.BerInteger;
 import com.beanit.asn1bean.ber.types.BerOctetString;
 import com.beanit.enums.eAuthInfo;
+import com.beanit.enums.eTerminate;
 import com.beanit.its.C2CAuthenticatedMessage;
 import com.beanit.its.HeaderOptions;
 import com.beanit.its.PDUs;
 import com.beanit.its.Terminate;
 import com.its.rota.server.dto.CenterDto;
 import com.its.rota.server.repository.ApplicationRepository;
-import io.netty.channel.ChannelFuture;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
 
@@ -17,34 +17,27 @@ import org.slf4j.MDC;
 public class AiTerminate {
 
     public static boolean run(CenterDto center) {
-        boolean result = true;
+        boolean result;
+        center.getNetState().terminate();
         try {
             MDC.put("id", center.getLogKey());
             log.info("AiTerminate.run: [{}, {}].", center.getLogKey(), center.getIpAddress());
 
             PDUs pdUs = new PDUs();
             byte[] auth = {eAuthInfo.AI_Terminate.getValue() };
-            Terminate terminate = new Terminate();
+            Terminate terminate = new Terminate(eTerminate.Terminate_Other.getValue());
             pdUs.setTerminate(terminate);
 
             HeaderOptions hdrOpts = ApplicationRepository.getHeaderOptions(center);
 
-            C2CAuthenticatedMessage resC2c = new C2CAuthenticatedMessage();
-            resC2c.setDatexAuthenticationInfoText(new BerOctetString(auth));
-            resC2c.setDatexDataPacketNumber(new BerInteger(center.getSeq().nextValue()));
-            resC2c.setDatexDataPacketPriorityNumber(new BerInteger(1));
-            resC2c.setOptions(hdrOpts);
-            resC2c.setPdu(pdUs);
+            C2CAuthenticatedMessage c2c = new C2CAuthenticatedMessage();
+            c2c.setDatexAuthenticationInfoText(new BerOctetString(auth));
+            c2c.setDatexDataPacketNumber(new BerInteger(center.getSeq().nextValue()));
+            c2c.setDatexDataPacketPriorityNumber(new BerInteger(1));
+            c2c.setOptions(hdrOpts);
+            c2c.setPdu(pdUs);
 
-            ChannelFuture f = center.getNetState().getChannel().writeAndFlush(resC2c);
-            f.awaitUninterruptibly();
-            if (f.isDone() || f.isSuccess()) {
-                log.info("AiTerminate.run: [{}, {}]. Packet send OK.", center.getLogKey(), center.getIpAddress());
-            }
-            else {
-                log.error("AiTerminate.run: [{}, {}]. Packet send Failed. will be closed.", center.getLogKey(), center.getIpAddress());
-                result = false;
-            }
+            result = center.sendData(c2c, "AI_Terminate");
         }
         catch (Exception e) {
             log.error("AiTerminate.run: [{}, {}]. Packet send Exception. will be closed. {}", center.getLogKey(), center.getIpAddress(), e.getMessage());

+ 17 - 117
src/main/java/com/its/rota/server/xnet/server/process/response/AcceptResponse.java

@@ -1,135 +1,35 @@
 package com.its.rota.server.xnet.server.process.response;
 
-import com.beanit.its.Accept;
 import com.beanit.its.C2CAuthenticatedMessage;
-import com.beanit.its.PDUs;
-import com.its.rota.server.config.ApplicationConfig;
 import com.its.rota.server.dto.CenterDto;
-import com.its.rota.server.process.dbms.DbmsDataProcess;
-import io.netty.channel.Channel;
 import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
 
 @Slf4j
 public class AcceptResponse implements ItsAsnResponse {
-    private CenterDto obj;
-    private Channel channel;
-    private C2CAuthenticatedMessage c2c;
-    private DbmsDataProcess dbmsDataProcess;
+    private final CenterDto center;
+    private final C2CAuthenticatedMessage c2c;
 
-    public AcceptResponse(CenterDto obj, DbmsDataProcess dbmsDataProcess, C2CAuthenticatedMessage c2c) {
-        this.obj = obj;
-        this.channel = obj.getNetState().getChannel();
+    public AcceptResponse(CenterDto center, C2CAuthenticatedMessage c2c) {
+        this.center = center;
         this.c2c = c2c;
-        this.dbmsDataProcess = dbmsDataProcess;
     }
 
     @Override
     public boolean response() {
-        String ipAddress = this.obj.getIpAddress();
-        log.info("AcceptResponse.response: {}", ipAddress);
-
-        PDUs pdus = this.c2c.getPdu();
-        Accept accept = pdus.getAccept();
-        if (accept == null) {
-            log.error("AcceptResponse.response: {}, accept data null", ipAddress);
-            return false;
+        boolean result = true;
+        try {
+            MDC.put("id", this.center.getLogKey());
+            log.info("AcceptResponse.response: [{}, {}].", this.center.getLogKey(), this.center.getIpAddress());
         }
-
-//        TbRseCtrlHs command = null;
-//        long dataPacketNmbr = c2c.getDatexDataPacketNumber().value.longValue();
-//        Long acceptPacketNmbr = accept.getDatexAcceptPacketNbr().value.longValue();
-//        Accept.DatexAcceptType acceptType = accept.getDatexAcceptType();
-//        if (acceptType.getLogIn() != null) {
-//            // Login = 1, 여기는 들어오지 않는다.
-//            log.info("AcceptResponse.response: {}. Login: {}, {}", ipAddress, dataPacketNmbr, acceptPacketNmbr);
-//            loginAccept(runningConfig);
-//        }
-//        else if (acceptType.getSingleSubscription() != null) {
-//            // SingleSubscription = 2
-//            // Publication = 3
-//            // 제어명령에 대한 응답, 제어목록에서 삭제하고 이력으로 저장한다.
-//            this.obj.removeRegisteredCommands(acceptPacketNmbr, true);
-//            command = this.obj.getUserCommands(acceptPacketNmbr);
-//            log.info("AcceptResponse.response: {}. SingleSubscription: {}, {}", ipAddress, dataPacketNmbr, acceptPacketNmbr);
-//        }
-//        else if (acceptType.getPublication() != null) {
-//            // SingleSubscription = 2
-//            // Publication = 3
-//            // 제어명령에 대한 응답, 제어목록에서 삭제하고 이력으로 저장한다.
-//            this.obj.removeRegisteredCommands(acceptPacketNmbr, true);
-//            command = this.obj.getUserCommands(acceptPacketNmbr);
-//            log.info("AcceptResponse.response: {}. Publication: {}, {}", ipAddress, dataPacketNmbr, acceptPacketNmbr);
-//        }
-//        else if (acceptType.getRegisteredSubscription() != null) {
-//            // RegisteredSubscription = 4
-//            // 요청에 대한 응답, 제어목록에서 삭제한다.
-//            // 상태정보요청: 269677936
-//            if (269677936 == acceptType.getRegisteredSubscription().longValue()) {
-//                if (acceptPacketNmbr == 1) {
-//                    /**
-//                     * requestObuGatherInfo 에 대한 Accept 응답
-//                     */
-//                    LoginDeviceService.getInstance().requestObuStatusInfo(this.obj, this.ctx.channel());
-//                }
-//                else if (acceptPacketNmbr == 2) {
-//                    /**
-//                     * requestObuStatusInfo 에 대한 Accept 응답
-//                     */
-//                    //LoginDeviceService.getInstance().requestObuStatusInfo(this.obj, this.ctx.channel());
-//                }
-//                //log.info("AcceptResponse.response: {}. 상태정보요청응답: {}, {}", ipAddress, dataPacketNmbr, acceptPacketNmbr);
-//            }
-//            this.obj.removeRegisteredCommands(acceptPacketNmbr, true);
-//            log.info("AcceptResponse.response: {}. RegisteredSubscription: {}, {}, {}", ipAddress, dataPacketNmbr, acceptPacketNmbr, acceptType.getRegisteredSubscription().longValue());
-//        }
-//
-//        if (command != null) {
-//            log.info("AcceptResponse.response: {}. Accept User Command: {}, {}", ipAddress, dataPacketNmbr, acceptPacketNmbr);
-//            this.obj.removeUserCommands(acceptPacketNmbr);
-//            // TODO: 제어명령 성공 전송(성공)
-//            command.setRspsType("0");  // 명령 성공으로 설정
-//            RseCtlrMapper mapper = (RseCtlrMapper) AppUtils.getBean(RseCtlrMapper.class);
-//            mapper.updateRseCtrlHs(command);
-//        }
-        return true;
+        catch (Exception e) {
+            log.error("AcceptResponse.response: [{}, {}]. Packet send Exception. will be closed. {}", this.center.getLogKey(), this.center.getIpAddress(), e.getMessage());
+            result = false;
+        }
+        finally {
+            MDC.clear();
+        }
+        return result;
     }
 
-    /**
-     * 클라이언트 모드 동작시 로그인 요청에 대한 응답으로 로그인 처리
-     * @param
-     */
-    private void loginAccept(ApplicationConfig config) {
-//        if (this.obj.getNetState() > NET.LOGIN_REQ && this.obj.getChannel() != null) {
-//            log.warn("AcceptResponse.loginAccept: {}, already login. older channel will be closed.", this.obj.getMcuID());
-//            this.obj.setDupLogin(true);
-//            this.obj.setDupChannel(this.obj.getChannel());
-////            DsrcAsn1ServerIdleStatePacketHandler.disconnectChannel(this.obj, this.obj.getDupChannel());
-//        }
-//
-//        this.obj.channelLoginInit();
-//        this.obj.getStts().initNormal();
-//
-//        TbRseCtlrCnncHs voLog = new TbRseCtlrCnncHs();
-//        voLog.setRSE_CTLR_NMBR(this.obj.getID());
-//        voLog.setLOG_ADDRESS(this.obj.getRSE_CTLR_IP());
-//        voLog.setLoginInfo(c2c);
-//        voLog.setLOG_ID(this.obj.getMcuID());
-//        voLog.setLOG_TYPE(Integer.toString(TbRseCtlrCnncHs.LOG_TYPE_LOGIN));
-//        this.obj.setLOG_ID(voLog.getLOG_ID());
-//        if (this.obj.isDupLogin()) {
-//            // 중복 접속(이미 통신중인 세션이 존재함)
-//            voLog.setLOG_TYPE(Integer.toString(TbRseCtlrCnncHs.LOG_TYPE_DUP_LOGIN));
-//        }
-//        this.dbmsDataProcess.add(new DbmsData(DbmsDataType.DBMS_DATA_LOG_HS, false, voLog));
-//
-//        this.obj.getSeq().resetValue();
-//        //this.obj.setLogin(login);
-//        // 로그인이 성공하면 제어기에 정보를 요청한다.
-//        log.info("AcceptResponse.loginAccept: {}, Request Subscriptions", obj.getMcuID());
-
-        /**
-         * OBU Gather Info request
-         */
-//        LoginDeviceService.getInstance().requestObuGatherInfo(this.obj, this.channel());
-    }
 }

+ 9 - 20
src/main/java/com/its/rota/server/xnet/server/process/response/FredResponse.java

@@ -9,7 +9,6 @@ import com.beanit.its.HeaderOptions;
 import com.beanit.its.PDUs;
 import com.its.rota.server.dto.CenterDto;
 import com.its.rota.server.repository.ApplicationRepository;
-import io.netty.channel.ChannelFuture;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
 
@@ -41,33 +40,23 @@ public class FredResponse implements ItsAsnResponse {
 
             HeaderOptions hdrOpts = ApplicationRepository.getHeaderOptions(this.center);
 
-            C2CAuthenticatedMessage resC2c = new C2CAuthenticatedMessage();
-            resC2c.setDatexAuthenticationInfoText(new BerOctetString(auth));
-            resC2c.setDatexDataPacketNumber(new BerInteger(this.center.getSeq().nextValue()));
-            resC2c.setDatexDataPacketPriorityNumber(new BerInteger(1));
-            resC2c.setOptions(hdrOpts);
-            resC2c.setPdu(pdUs);
+            C2CAuthenticatedMessage c2c = new C2CAuthenticatedMessage();
+            c2c.setDatexAuthenticationInfoText(new BerOctetString(auth));
+            c2c.setDatexDataPacketNumber(new BerInteger(this.center.getSeq().nextValue()));
+            c2c.setDatexDataPacketPriorityNumber(new BerInteger(1));
+            c2c.setOptions(hdrOpts);
+            c2c.setPdu(pdUs);
 
-            ChannelFuture f = this.center.getNetState().getChannel().writeAndFlush(resC2c);
-            f.awaitUninterruptibly();
-            if (f.isDone() || f.isSuccess()) {
-                log.info("FredResponse.response: [{}, {}]. Packet send OK.", this.center.getLogKey(), this.center.getIpAddress());
-            }
-            else {
-                result = false;
-                log.error("FredResponse.response: [{}, {}]. Packet send Failed. will be closed.", this.center.getLogKey(), this.center.getIpAddress());
-            }
-            center.getNetState().loginOk();
-
-            return result;
+            result = this.center.sendData(c2c, "AI_FrED");
         }
         catch (Exception e) {
             log.error("FredResponse.response: [{}, {}]. Packet send Exception. will be closed. {}", this.center.getLogKey(), this.center.getIpAddress(), e.getMessage());
-            return false;
+            result = false;
         }
         finally {
             MDC.clear();
         }
+        return result;
     }
 
 }

+ 6 - 16
src/main/java/com/its/rota/server/xnet/server/process/response/LoginResponse.java

@@ -10,7 +10,6 @@ import com.beanit.its.*;
 import com.beanit.utils.ItsAsnUtils;
 import com.its.rota.server.dto.CenterDto;
 import com.its.rota.server.repository.ApplicationRepository;
-import io.netty.channel.ChannelFuture;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
 
@@ -28,7 +27,7 @@ public class LoginResponse implements ItsAsnResponse {
 
     @Override
     public boolean response() {
-        boolean result = true;
+        boolean result;
         try {
             MDC.put("id", this.center.getLogKey());
             log.info("LoginResponse.response: [{}, {}].", this.center.getLogKey(), this.center.getIpAddress());
@@ -83,8 +82,6 @@ public class LoginResponse implements ItsAsnResponse {
             PDUs pdUs = new PDUs();
 
             if (rejectLogin != eRejectLogin.Reject_Login_cd_other) {
-                result = false;
-
                 auth[0] = eAuthInfo.AI_Reject.getValue();
 
                 RejectType rjtType = new RejectType();
@@ -118,26 +115,19 @@ public class LoginResponse implements ItsAsnResponse {
             resC2c.setOptions(hdrOpts);
             resC2c.setPdu(pdUs);
 
-            ChannelFuture f = this.center.getNetState().getChannel().writeAndFlush(resC2c);
-            f.awaitUninterruptibly();
-            if (f.isDone() || f.isSuccess()) {
-                log.info("LoginResponse.response: [{}, {}]. Packet send OK.", this.center.getLogKey(), this.center.getIpAddress());
-            }
-            else {
-                result = false;
-                log.error("LoginResponse.response: [{}, {}]. Packet send Failed. will be closed.", this.center.getLogKey(), this.center.getIpAddress());
+            result = this.center.sendData(resC2c, "AI_Login-Response");
+            if (result) {
+                this.center.getNetState().loginOk();
             }
-            center.getNetState().loginOk();
-
-            return result;
         }
         catch (Exception e) {
             log.error("LoginResponse.response: [{}, {}]. Packet send Exception. will be closed. {}", this.center.getLogKey(), this.center.getIpAddress(), e.getMessage());
-            return false;
+            result = false;
         }
         finally {
             MDC.clear();
         }
+        return result;
     }
 
 }

+ 19 - 25
src/main/java/com/its/rota/server/xnet/server/process/response/LogoutResponse.java

@@ -1,42 +1,36 @@
 package com.its.rota.server.xnet.server.process.response;
 
 import com.beanit.its.C2CAuthenticatedMessage;
-import com.its.app.common.utils.NettyUtils;
-import com.its.rota.server.common.SpringUtils;
-import com.its.rota.server.config.ApplicationConfig;
 import com.its.rota.server.dto.CenterDto;
-import com.its.rota.server.process.dbms.DbmsDataProcess;
-import io.netty.channel.ChannelHandlerContext;
+import com.its.rota.server.repository.ApplicationRepository;
 import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
 
 @Slf4j
 public class LogoutResponse implements ItsAsnResponse {
-    private CenterDto obj;
-    private ChannelHandlerContext ctx;
-    private C2CAuthenticatedMessage c2c;
+    private final CenterDto center;
+    private final C2CAuthenticatedMessage c2c;
 
-    private DbmsDataProcess dbmsDataProcess;
-
-    public LogoutResponse(CenterDto obj, ChannelHandlerContext ctx, C2CAuthenticatedMessage c2c) {
-        this.obj = obj;
-        this.ctx = ctx;
+    public LogoutResponse(CenterDto center, C2CAuthenticatedMessage c2c) {
+        this.center = center;
         this.c2c = c2c;
-        this.dbmsDataProcess = SpringUtils.getBean(DbmsDataProcess.class);
     }
 
     @Override
     public boolean response() {
-        String ipAddress = NettyUtils.getRemoteIpAddress(this.ctx.channel());
-        log.info("LogoutResponse.response: {}", ipAddress);
-
-        // 로그아웃 정보를 데이터베이스에 저장.
-        if (this.dbmsDataProcess != null) {
-//            TbRseCtlrCnncHs voLog = new TbRseCtlrCnncHs();
-//            voLog.setRSE_CTLR_NMBR(this.obj.getID());
-//            voLog.setLOG_ADDRESS(NettyUtils.getRemoteIpAddress(this.ctx.channel()));
-//            voLog.setLoginInfo(this.c2c);
-//            this.dbmsDataProcess.add(new DbmsData(DbmsDataType.DBMS_DATA_LOG_HS, false, voLog));
+        boolean result = true;
+        try {
+            MDC.put("id", this.center.getLogKey());
+            log.info("LogoutResponse.response: [{}, {}].", this.center.getLogKey(), this.center.getIpAddress());
+            ApplicationRepository.closeChannel(this.center, this.center.getNetState().getChannel());
+        }
+        catch (Exception e) {
+            log.error("LogoutResponse.response: [{}, {}]. Packet send Exception. will be closed. {}", this.center.getLogKey(), this.center.getIpAddress(), e.getMessage());
+            result = false;
+        }
+        finally {
+            MDC.clear();
         }
-        return true;
+        return result;
     }
 }

+ 93 - 81
src/main/java/com/its/rota/server/xnet/server/process/response/SubscriptionResponse.java

@@ -1,103 +1,115 @@
 package com.its.rota.server.xnet.server.process.response;
 
-import com.beanit.its.C2CAuthenticatedMessage;
-import com.beanit.its.PDUs;
-import com.its.app.common.utils.NettyUtils;
+import com.beanit.asn1bean.ber.types.BerEnum;
+import com.beanit.enums.eObjectId;
+import com.beanit.enums.eRejectSubscription;
+import com.beanit.its.*;
+import com.beanit.utils.ItsAsnUtils;
 import com.its.rota.server.dto.CenterDto;
+import com.its.rota.server.xnet.server.process.request.AiAccept;
+import com.its.rota.server.xnet.server.process.request.AiReject;
 import com.its.rota.server.xnet.server.process.service.SubscriptionService;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandlerContext;
+import com.its.rota.server.xnet.server.process.service.impl.SubscriptionRegisterService;
+import com.its.rota.server.xnet.server.process.service.impl.SubscriptionSingleService;
 import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
 
 @Slf4j
 public class SubscriptionResponse implements ItsAsnResponse {
-    private CenterDto obj;
-    private ChannelHandlerContext ctx;
-    private C2CAuthenticatedMessage c2c;
+    private final CenterDto center;
+    private final C2CAuthenticatedMessage c2c;
 
-    public SubscriptionResponse(CenterDto obj, ChannelHandlerContext ctx, C2CAuthenticatedMessage c2c) {
-        this.obj = obj;
-        this.ctx = ctx;
+    public SubscriptionResponse(CenterDto center, C2CAuthenticatedMessage c2c) {
+        this.center = center;
         this.c2c = c2c;
     }
 
     @Override
     public boolean response() {
-        String ipAddress = NettyUtils.getRemoteIpAddress(this.ctx.channel());
-        log.debug("SubscriptionResponse.response: {}", ipAddress);
+        // AI_Accept or AI_Reject 로 응답
+        boolean result = true;
+        boolean accepted = true;
+        try {
+            MDC.put("id", this.center.getLogKey());
+            log.info("SubscriptionResponse.response: [{}, {}].", this.center.getLogKey(), this.center.getIpAddress());
 
-        int dataPacketNmbr = this.c2c.getDatexDataPacketNumber().intValue();
-        int objectId = 0;
-        SubscriptionService subscriptionService = null;
-        C2CAuthenticatedMessage resC2c = null;
-        PDUs pdus = this.c2c.getPdu();
-//        Subscription subscription = pdus.getSubscription();
-//        if (subscription != null) {
-//            int subscribeSerialNbr = subscription.getDatexSubscribeSerialNbr().intValue();
-//            SubscriptionType subscriptionType = subscription.getDatexSubscribeType();
-//            BerEnum cancelReasonCd = subscriptionType.getDatexSubscribeCancelReasonCd();
-//            if (subscriptionType != null) {
-//                SubscriptionData subscriptionData = subscriptionType.getSubscription();
-//                if (subscriptionData != null) {
-//                    boolean persistentBool = subscriptionData.getDatexSubscribePersistentBool().value;
-//                    int statusCd           = subscriptionData.getDatexSubscribeStatusCd().value.intValue();   // new, update
-//                    int publishFormatCd    = subscriptionData.getDatexSubscribePublishFormatCd().value.intValue();
-//                    int priorityNbr        = subscriptionData.getDatexSubscriptionPriorityNbr().value.intValue();
-//                    boolean guaranteeBool  = subscriptionData.getDatexSubscribeGuaranteeBool().value;
-//
-//                    objectId = DsrcAsn1Utils.getObjectId(subscriptionData.getDatexSubscribePdu().getEndApplicationMessageId().value);
-//                    //log.info("SubscriptionResponse.response: objectId: {}", objectId);
-//
-//                    if (objectId != eObjectId.OBJ_ProbeVehicleDetectionRoadSide.getValue() &&
-//                        objectId  > eObjectId.OBJ_DSRCRecentOBUTransactionInfo.getValue()) {
-//                        // Reject
-//                        resC2c = DsrcAsn1Reject.makeC2CAuthenticatedMessage(this.obj, this.ctx.channel(), this.c2c,
-//                                eRejectSubscription.Reject_Subscription_cd_invalidSubscriptionMsgId.getValue());
-//                        log.info("SubscriptionResponse.response: {}, Reject, objectId: {}", ipAddress, objectId);
-//                    }
-//                    else {
-//                        SubscriptionMode subscriptionMode = subscriptionData.getDatexSubscribeMode();
-//                        if (subscriptionMode != null) {
-//                            // subscriptionMode = single, event-driven, periodic
-//                            if (subscriptionMode.getSingle() != null) {
-//                                //log.info("SubscriptionResponse.response: {}, SubscriptionSingleService", ipAddress);
-//                                subscriptionService = SubscriptionSingleService.getInstance();
-//                            } else if (subscriptionMode.getEventDriven() != null) {
-//                                //log.info("SubscriptionResponse.response: {}, SubscriptionRegisterService[EventDriven]", ipAddress);
-//                                subscriptionService = SubscriptionRegisterService.getInstance();
-//                            } else if (subscriptionMode.getPeriodic() != null) {
-//                                //log.info("SubscriptionResponse.response: {}, SubscriptionRegisterService[Periodic]", ipAddress);
-//                                subscriptionService = SubscriptionRegisterService.getInstance();
-//                            }
-//                            if (guaranteeBool) {
-//                                resC2c = DsrcAsn1Accept.makeC2CAuthenticatedMessage(this.obj, this.ctx.channel(), this.c2c);
-//                            }
-//                        } else {
-//                            log.warn("SubscriptionResponse.response: {}, SubscriptionMode null", ipAddress);
-//                        }
-//                    }
-//                }
-//            } else if (cancelReasonCd != null) {
-//                // Cancel
-//                int cancelReasonId = cancelReasonCd.value.intValue();
-//                resC2c = DsrcAsn1Accept.makeC2CAuthenticatedMessage(this.obj, this.ctx.channel(), this.c2c);
-//                log.info("SubscriptionResponse.response: {}, Accept, cancelReasonCd: {}", ipAddress, cancelReasonId);
-//            }
-//        }
+            int dataPacketNmbr = this.c2c.getDatexDataPacketNumber().intValue();
+            int objectId = 0;
+            SubscriptionService subscriptionService = null;
+            C2CAuthenticatedMessage c2c = null;
+            PDUs pdUs = this.c2c.getPdu();
+            Subscription subscription = pdUs.getSubscription();
+            if (subscription != null) {
+                int subscribeSerialNbr = subscription.getDatexSubscribeSerialNbr().intValue();
+                SubscriptionType subscriptionType = subscription.getDatexSubscribeType();
+                BerEnum cancelReasonCd = subscriptionType.getDatexSubscribeCancelReasonCd();
+                if (subscriptionType != null) {
+                    SubscriptionData subscriptionData = subscriptionType.getSubscription();
+                    if (subscriptionData != null) {
+//                        boolean persistentBool = subscriptionData.getDatexSubscribePersistentBool().value;
+//                        int statusCd           = subscriptionData.getDatexSubscribeStatusCd().value.intValue();   // new, update
+//                        int publishFormatCd    = subscriptionData.getDatexSubscribePublishFormatCd().value.intValue();
+//                        int priorityNbr        = subscriptionData.getDatexSubscriptionPriorityNbr().value.intValue();
+                        boolean guaranteeBool  = subscriptionData.getDatexSubscribeGuaranteeBool().value;
 
-//        if (subscriptionService != null) {
-//            subscriptionService.response(this.obj, this.ctx.channel(), objectId, subscription);
-//        }
+                        objectId = ItsAsnUtils.getObjectId(subscriptionData.getDatexSubscribePdu().getEndApplicationMessageId().value);
+                        log.info("SubscriptionResponse.response: [{}, {}]. objectId: {}", this.center.getLogKey(), this.center.getIpAddress(), objectId);
 
-        if (resC2c != null) {
-            // send accept or reject
-            ChannelFuture f = this.ctx.channel().writeAndFlush(resC2c);
-            f.awaitUninterruptibly();
-            if (!f.isDone() && !f.isSuccess()) {
-                log.error("SubscriptionResponse.response: {}. packet send Failed.", ipAddress);
+                        if (objectId < eObjectId.OBJ_CurrentLinkState.getValue() && objectId  > eObjectId.OBJ_DetectorCollection.getValue()) {
+                            // Reject
+                            accepted = false;
+                            c2c = AiReject.makeMessage(this.center, this.c2c, eRejectSubscription.Reject_Subscription_cd_invalidSubscriptionMsgId.getValue());
+                            log.info("SubscriptionResponse.response: [{}, {}]. objectId: {}, Reject.", this.center.getLogKey(), this.center.getIpAddress(), objectId);
+                        }
+                        else {
+                            SubscriptionMode subscriptionMode = subscriptionData.getDatexSubscribeMode();
+                            if (subscriptionMode != null) {
+                                // subscriptionMode = single, event-driven, periodic
+                                if (subscriptionMode.getSingle() != null) {
+                                    log.info("SubscriptionResponse.response: [{}, {}]. subscriptionMode-Single.", this.center.getLogKey(), this.center.getIpAddress());
+                                    subscriptionService = SubscriptionSingleService.getInstance();
+                                } else if (subscriptionMode.getEventDriven() != null) {
+                                    log.info("SubscriptionResponse.response: [{}, {}]. subscriptionMode-EventDriven.", this.center.getLogKey(), this.center.getIpAddress());
+                                    subscriptionService = SubscriptionRegisterService.getInstance();
+                                } else if (subscriptionMode.getPeriodic() != null) {
+                                    log.info("SubscriptionResponse.response: [{}, {}]. subscriptionMode-Periodic.", this.center.getLogKey(), this.center.getIpAddress());
+                                    subscriptionService = SubscriptionRegisterService.getInstance();
+                                }
+                                if (guaranteeBool) {
+                                    c2c = AiAccept.makeMessage(this.center, this.c2c);
+                                }
+                            }
+                            else {
+                                log.warn("SubscriptionResponse.response: [{}, {}]. subscriptionMode is null.", this.center.getLogKey(), this.center.getIpAddress());
+                            }
+                        }
+                    }
+                }
+                else if (cancelReasonCd != null) {
+                    // Cancel
+                    int cancelReasonId = cancelReasonCd.value.intValue();
+                    c2c = AiAccept.makeMessage(this.center, this.c2c);
+                    log.info("SubscriptionResponse.response: [{}, {}]. Accept, cancelReasonCd: {}.", this.center.getLogKey(), this.center.getIpAddress(), cancelReasonId);
+                }
             }
+
+            if (subscriptionService != null) {
+//                subscriptionService.response(this.obj, this.ctx.channel(), objectId, subscription);
+            }
+
+            if (c2c != null) {
+                String sendMsg = accepted ? "AI_Subscription-AI_Accept" : "AI_Subscription-AI_Reject";
+                result = this.center.sendData(c2c, sendMsg);
+            }
+        }
+        catch (Exception e) {
+            log.error("SubscriptionResponse.response: [{}, {}]. Packet send Exception. will be closed. {}", this.center.getLogKey(), this.center.getIpAddress(), e.getMessage());
+            result = false;
+        }
+        finally {
+            MDC.clear();
         }
-        return true;
+        return result;
     }
 
 }

+ 13 - 18
src/main/java/com/its/rota/server/xnet/server/process/response/TerminateResponse.java

@@ -1,36 +1,31 @@
 package com.its.rota.server.xnet.server.process.response;
 
 import com.beanit.its.C2CAuthenticatedMessage;
-import com.its.app.common.utils.NettyUtils;
-import com.its.rota.server.config.ApplicationConfig;
 import com.its.rota.server.dto.CenterDto;
-import io.netty.channel.ChannelHandlerContext;
+import com.its.rota.server.repository.ApplicationRepository;
 import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
 
 @Slf4j
 public class TerminateResponse implements ItsAsnResponse {
-    private CenterDto obj;
-    private ChannelHandlerContext ctx;
-    private C2CAuthenticatedMessage c2c;
+    private final CenterDto center;
+    private final C2CAuthenticatedMessage c2c;
 
-    public TerminateResponse(CenterDto obj, ChannelHandlerContext ctx, C2CAuthenticatedMessage c2c) {
-        this.obj = obj;
-        this.ctx = ctx;
+    public TerminateResponse(CenterDto center, C2CAuthenticatedMessage c2c) {
+        this.center = center;
         this.c2c = c2c;
     }
 
     @Override
     public boolean response() {
-        if (this.obj == null) {
-            return false;
+        try {
+            MDC.put("id", this.center.getLogKey());
+            log.info("TerminateResponse.response: [{}, {}].", this.center.getLogKey(), this.center.getIpAddress());
+            ApplicationRepository.closeChannel(this.center, this.center.getNetState().getChannel());
+        }
+        finally {
+            MDC.clear();
         }
-
-        // 처리내용 없음.
-        String ipAddress = NettyUtils.getRemoteIpAddress(this.ctx.channel());
-        log.info("TerminateResponse.response: {}", ipAddress);
-
-        //Terminate terminate = new Terminate(eTerminate.Terminate_ClientCommProblesm.getValue());
-//        ControlDeviceService.getInstance().sendTerminate(this.obj, this.ctx.channel(), eTerminate.Terminate_Other.getValue());
         return true;
     }
 }

+ 2 - 2
src/main/java/com/its/rota/server/xnet/server/process/service/impl/SubscriptionRegisterService.java

@@ -48,7 +48,7 @@ public class SubscriptionRegisterService implements SubscriptionService {
         try {
             Registered registered = null;
             int subscribeSerialNbr = subscription.getDatexSubscribeSerialNbr().value.intValue();
-            SubscriptionData subscriptionData = subscription.getDatexSubscribeType().getChoice().getSubscription();
+            SubscriptionData subscriptionData = subscription.getDatexSubscribeType().getSubscription();
 
             if (subscriptionData.getDatexSubscribeMode().getEventDriven() != null) {
                 registered = subscriptionData.getDatexSubscribeMode().getEventDriven();
@@ -108,7 +108,7 @@ public class SubscriptionRegisterService implements SubscriptionService {
         try {
             Registered registered = null;
             int subscribeSerialNbr = subscription.getDatexSubscribeSerialNbr().value.intValue();
-            SubscriptionData subscriptionData = subscription.getDatexSubscribeType().getChoice().getSubscription();
+            SubscriptionData subscriptionData = subscription.getDatexSubscribeType().getSubscription();
 
             if (subscriptionData.getDatexSubscribeMode().getEventDriven() != null) {
                 registered = subscriptionData.getDatexSubscribeMode().getEventDriven();

+ 1 - 1
src/main/java/com/its/rota/server/xnet/server/process/service/impl/SubscriptionSingleService.java

@@ -46,7 +46,7 @@ public class SubscriptionSingleService implements SubscriptionService {
         byte[] auth = null;//{ (byte) eAuthInfo.AI_NonCryptObu.getValue() };
 
         try {
-            SubscriptionData subscriptionData = subscription.getDatexSubscribeType().getChoice().getSubscription();
+            SubscriptionData subscriptionData = subscription.getDatexSubscribeType().getSubscription();
 //            ControlDeviceList list = new ControlDeviceList();
 //            byte[] inBytes = subscriptionData.getDatexSubscribePdu().getEndApplicationMessageMsg().value;
 //            list.decode(new ByteArrayInputStream(inBytes, 0, inBytes.length));