|
@@ -16,6 +16,8 @@ import org.slf4j.MDC;
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
+import static com.its.vds.xnettcp.vds.protocol.VdsProtocol.vds_DLE;
|
|
|
+
|
|
|
@Slf4j
|
|
|
public class VdsTcpClientDecoder extends ByteToMessageDecoder {
|
|
|
|
|
@@ -26,13 +28,13 @@ public class VdsTcpClientDecoder extends ByteToMessageDecoder {
|
|
|
Channel channel = ctx.channel();
|
|
|
TbVdsCtlr obj = AppRepository.getInstance().getCtlrIpMap().get(ipAddress);
|
|
|
if (obj == null) {
|
|
|
- log.error("TcpServerDecoder.decode: Unknown Controller IP: {}. will be close.", ipAddress);
|
|
|
+ log.error("VdsTcpClientDecoder.decode: Unknown Controller IP: {}. will be close.", ipAddress);
|
|
|
VdsTcpClientIdleHandler.disconnectChannel(channel);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (!channel.isOpen() || !channel.isActive()) {
|
|
|
- log.error("TcpServerDecoder.decode: {}, isOpen: {}, isActive: {}. [{}]", ipAddress, channel.isOpen(), channel.isActive(), obj.getLogKey());
|
|
|
+ log.error("VdsTcpClientDecoder.decode: {}, isOpen: {}, isActive: {}. [{}]", ipAddress, channel.isOpen(), channel.isActive(), obj.getLogKey());
|
|
|
VdsTcpClientIdleHandler.disconnectChannel(channel);
|
|
|
return;
|
|
|
}
|
|
@@ -45,12 +47,7 @@ public class VdsTcpClientDecoder extends ByteToMessageDecoder {
|
|
|
if (obj.isDump()) {
|
|
|
byte[] debugBytes = new byte[byteBuf.readableBytes()];
|
|
|
byteBuf.getBytes(byteBuf.readerIndex(), debugBytes);
|
|
|
- log.info("RECV: [{}], {} Bytes. {}", ipAddress, debugBytes.length, SysUtils.byteArrayToHex(debugBytes));
|
|
|
- }
|
|
|
-
|
|
|
- if (readableBytes < VdsProtocol.MIN_PACKET_SIZE) {
|
|
|
- log.error("RECV: {}. byteBuf.readableBytes() == 0. [{]{}]", ipAddress, obj.getLogKey());
|
|
|
- return;
|
|
|
+ log.info("RECV_0: [{}], {} Bytes. {}", ipAddress, debugBytes.length, SysUtils.byteArrayToHex(debugBytes));
|
|
|
}
|
|
|
|
|
|
byteBuf.markReaderIndex();
|
|
@@ -58,66 +55,68 @@ public class VdsTcpClientDecoder extends ByteToMessageDecoder {
|
|
|
byte[] packets = new byte[readableBytes];
|
|
|
byteBuf.readBytes(recvBytes);
|
|
|
|
|
|
- int readIdx = 0;
|
|
|
+ int stuffing = 0;
|
|
|
int msgSize = 0; // 순수 데이터 사이즈
|
|
|
- int totalMsgSize = 0; // 전체 수신한 패킷 사이즈
|
|
|
boolean foundDle = false;
|
|
|
- boolean remainPacket = false;
|
|
|
-
|
|
|
- while (true) {
|
|
|
- if (VdsProtocol.MIN_PACKET_SIZE > (readableBytes-totalMsgSize)) {
|
|
|
- break;
|
|
|
+ boolean requiredEtx = false;
|
|
|
+ for (int readIdx = 0; readIdx < readableBytes; readIdx++) {
|
|
|
+ if (readIdx == 2) {
|
|
|
+ if (recvBytes[0] != VdsProtocol.vds_DLE || recvBytes[1] != VdsProtocol.vds_STX) {
|
|
|
+ log.error("RECV_0: [{}]. DLE/STX Data Error. {}/{}", ipAddress, recvBytes[0], recvBytes[1]);
|
|
|
+ VdsTcpClientIdleHandler.disconnectChannel(channel);
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- msgSize = 0;
|
|
|
- foundDle = false;
|
|
|
- for (readIdx = totalMsgSize; readIdx < readableBytes; readIdx++) {
|
|
|
- byte data = recvBytes[readIdx];
|
|
|
- if (foundDle) {
|
|
|
- foundDle = false;
|
|
|
- if (data == VdsProtocol.vds_DLE) {
|
|
|
- // Skip DLE Stuffing Data
|
|
|
- log.warn("RECV_0: [{}]. ReadableBytes: {} Bytes, ReadIndex: {}, DLE Stuffing Data Recv.", ipAddress, readableBytes, readIdx);
|
|
|
- } else if (data == VdsProtocol.vds_STX) {
|
|
|
- // Packet
|
|
|
- packets[msgSize++] = data;
|
|
|
- } else if (data == VdsProtocol.vds_ETX) {
|
|
|
- // 이전데이터가 DLE 이고 현재 데이터가 ETX 이면 패킷의 끝임.
|
|
|
- // 다음 2바이트는 CRC 데이터임, 남아 있는 데이터가 CRC 2바이트를 포함한 크기보다 작으면
|
|
|
- // 하나의 패킷을 완전히 수신하지 못한 것임
|
|
|
- if ((readIdx + 3) > (readableBytes)) {
|
|
|
- // 하나의 패킷을 읽지 못함
|
|
|
- remainPacket = true;
|
|
|
- log.warn("RECV_0: [{}]. ReadableBytes: {} Bytes, ReadIndex: {}, DLE Data Remain.", ipAddress, readableBytes, readIdx);
|
|
|
- break;
|
|
|
- }
|
|
|
- packets[msgSize++] = data;
|
|
|
- packets[msgSize++] = recvBytes[readIdx+1]; // CRC1
|
|
|
- packets[msgSize++] = recvBytes[readIdx+2]; // CRC2
|
|
|
-
|
|
|
- // 하나의 패킷을 읽었음 ***************
|
|
|
- totalMsgSize += msgSize;
|
|
|
- byteBuf.readerIndex(msgSize);
|
|
|
- byteBuf.markReaderIndex();
|
|
|
- byteBuf.discardReadBytes();
|
|
|
-
|
|
|
- VdsResFramePacket packet = new VdsResFramePacket(obj, packets, msgSize);
|
|
|
- log.info("OnePacket: {} Bytes, {}", packet.getByteBuffer().array().length, SysUtils.byteArrayToHex(packet.getByteBuffer().array()));
|
|
|
- list.add(packet);
|
|
|
+ byte data = recvBytes[readIdx];
|
|
|
+ if (foundDle) {
|
|
|
+ foundDle = false;
|
|
|
+ if (data == VdsProtocol.vds_DLE) {
|
|
|
+ // Skip DLE Stuffing Data
|
|
|
+ stuffing++;
|
|
|
+ //log.warn("RECV_0: [{}]. ReadableBytes: {} Bytes, ReadIndex: {}, DLE Stuffing Data Recv.", ipAddress, readableBytes, readIdx);
|
|
|
+ } else if (data == VdsProtocol.vds_STX) {
|
|
|
+ // Packet
|
|
|
+ packets[msgSize++] = data;
|
|
|
+ } else if (data == VdsProtocol.vds_ETX) {
|
|
|
+ packets[msgSize++] = data;
|
|
|
+
|
|
|
+ // 이전데이터가 DLE 이고 현재 데이터가 ETX 이면 패킷의 끝임.
|
|
|
+ // 다음 2바이트는 CRC 데이터임, 남아 있는 데이터가 CRC 2바이트를 포함한 크기보다 작으면
|
|
|
+ // 하나의 패킷을 완전히 수신하지 못한 것임
|
|
|
+ if ((readIdx + 2) > (readableBytes)) {
|
|
|
+ // 하나의 패킷을 읽지 못함
|
|
|
+ log.warn("RECV_0: [{}]. ReadableBytes: {} Bytes, ReadIndex: {}, DLE Data Remain.", ipAddress, readableBytes, readIdx);
|
|
|
break;
|
|
|
+ }
|
|
|
+ packets[msgSize++] = recvBytes[readIdx+1]; // CRC1
|
|
|
+ packets[msgSize++] = recvBytes[readIdx+2]; // CRC2
|
|
|
+
|
|
|
+ // 하나의 패킷을 읽었음 ***************
|
|
|
+ byteBuf.readerIndex(readIdx+3);
|
|
|
+ byteBuf.markReaderIndex();
|
|
|
+ byteBuf.discardReadBytes();
|
|
|
+
|
|
|
+ VdsResFramePacket frame = new VdsResFramePacket(obj, packets, msgSize);
|
|
|
+ if (frame.getHead().getOpCode() == VdsProtocol.vds_Image) {
|
|
|
+ log.info("OneFramePacket: {} Bytes, vds_Image, stuffing {}", frame.getByteBuffer().array().length, stuffing);
|
|
|
} else {
|
|
|
- // DLE 다음에 와야할 데이터가 들어오지 않았다. 패킷에 오류가 발생함.
|
|
|
- log.warn("RECV_0: [{}]. ReadableBytes: {} Bytes, ReadIndex: {}, DLE Next Data Recv Error.", ipAddress, readableBytes, readIdx);
|
|
|
+ log.info("OneFramePacket: {} Bytes, stuffing {} {}", frame.getByteBuffer().array().length, stuffing, SysUtils.byteArrayToHex(frame.getByteBuffer().array()));
|
|
|
}
|
|
|
+
|
|
|
+ list.add(frame);
|
|
|
+ break;
|
|
|
} else {
|
|
|
- packets[msgSize++] = data;
|
|
|
- if (data == VdsProtocol.vds_DLE) {
|
|
|
- foundDle = true;
|
|
|
- }
|
|
|
+ // DLE 다음에 와야할 데이터가 들어오지 않았다. 패킷에 오류가 발생함.
|
|
|
+ log.error("RECV_0: [{}]. ReadableBytes: {} Bytes, ReadIndex: {}, DLE Next Data Recv Error.", ipAddress, readableBytes, readIdx);
|
|
|
+ VdsTcpClientIdleHandler.disconnectChannel(channel);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ packets[msgSize++] = data;
|
|
|
+ if (data == vds_DLE) {
|
|
|
+ foundDle = true;
|
|
|
}
|
|
|
- }
|
|
|
- if (totalMsgSize >= readableBytes || remainPacket) {
|
|
|
- break;
|
|
|
}
|
|
|
}
|
|
|
}
|