From e34324dfdbd779bbd03d8b49727b7845d70fb1d0 Mon Sep 17 00:00:00 2001
From: vincentlu <t1341870251@gmail.com>
Date: 星期一, 17 十一月 2025 16:21:58 +0800
Subject: [PATCH] #
---
zy-acs-gateway/src/main/java/com/zy/acs/gateway/utils/PacCoder.java | 306 +++++++++++++++++++++++++++++++++++++++++++++++++++
zy-acs-gateway/src/main/java/com/zy/acs/gateway/job/PacTask.java | 2
zy-acs-gateway/src/main/resources/application.yml | 2
3 files changed, 309 insertions(+), 1 deletions(-)
diff --git a/zy-acs-gateway/src/main/java/com/zy/acs/gateway/job/PacTask.java b/zy-acs-gateway/src/main/java/com/zy/acs/gateway/job/PacTask.java
index da19e96..fcb3ea7 100644
--- a/zy-acs-gateway/src/main/java/com/zy/acs/gateway/job/PacTask.java
+++ b/zy-acs-gateway/src/main/java/com/zy/acs/gateway/job/PacTask.java
@@ -34,6 +34,8 @@
, uniqueNo
, String.format("%02x", agvPackage.getHeader().getProtocolType().getCode()).toUpperCase()
);
+
+ // log.info("Agv [{}] 涓嬭 [{}] >>> {}", uniqueNo, agvPackage.getHeader().getProtocolType().getDes(), PacCoder.encode(agvPackage));
return;
}
channel.writeAndFlush(pac);
diff --git a/zy-acs-gateway/src/main/java/com/zy/acs/gateway/utils/PacCoder.java b/zy-acs-gateway/src/main/java/com/zy/acs/gateway/utils/PacCoder.java
new file mode 100644
index 0000000..7230fad
--- /dev/null
+++ b/zy-acs-gateway/src/main/java/com/zy/acs/gateway/utils/PacCoder.java
@@ -0,0 +1,306 @@
+package com.zy.acs.gateway.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.zy.acs.common.constant.RedisConstant;
+import com.zy.acs.common.domain.protocol.IMessageBody;
+import com.zy.acs.common.utils.RedisSupport;
+import com.zy.acs.common.utils.Utils;
+import com.zy.acs.framework.common.Cools;
+import com.zy.acs.framework.common.RadixTools;
+import com.zy.acs.gateway.constant.DirectionType;
+import com.zy.acs.gateway.constant.PacErrorType;
+import com.zy.acs.gateway.constant.PackagePart;
+import com.zy.acs.gateway.constant.ProtocolType;
+import com.zy.acs.gateway.domain.AgvPackage;
+import com.zy.acs.gateway.domain.PacHeader;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.buffer.Unpooled;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class PacCoder {
+
+ // {@link com.zy.acs.gateway.job.PacTask#run()}
+ // log.info("Agv [{}] 涓嬭 [{}] >>> {}", uniqueNo, agvPackage.getHeader().getProtocolType().getDes(), PacCoder.encode(agvPackage));
+ public static void main(String[] args) {
+ // 涓婄嚎
+ String agvNo = "18";
+ RedisSupport redis = RedisSupport.defaultRedisSupport;
+ redis.setObject(RedisConstant.AGV_ONLINE_FLAG, agvNo, 1, 1000);
+
+ // 瑙g爜 ------------------------------------------------------------------------------
+// String hexStr = "AA3000660000006709C5671287000000FFFF06005C2F33430300B1C7C05C2F3343000000000000000000000000A6FF40020C03FD0AAA4000660000006709C56711323332373631373236303834353530360387000000B4000000000000000000000000000000000000000000000000000000000000000000E83B";
+ String hexStr = "AA30000E0000006709C56712E600000001000000BCC9B24200808971C0BCC9B2420000000000000000000000005A0000020C0070B3";
+ AgvPackage pac = decode(hexStr);
+ System.out.println(JSON.toJSONString(pac));
+
+ // 缂栫爜 ------------------------------------------------------------------------------
+ String encodeHex = encode(pac);
+ System.out.println("缂栫爜鎶ユ枃 ===>> " + encodeHex);
+ }
+
+ public static int maxFrameLength = 4096;
+
+ public static AgvPackage decode(String hex) {
+ System.out.println("瑙g爜鎶ユ枃 ===>> " + hex.toUpperCase());
+ byte[] bytes = RadixTools.hexStringToBytes(hex);
+// ByteBuf in = Unpooled.buffer();
+ ByteBuf in = Unpooled.wrappedBuffer(bytes);
+
+ int startMark = indexOfStartMark(in);
+ if (startMark == -1){
+ in.skipBytes(in.readableBytes());
+ return null;
+ }
+ if (in.readableBytes() > maxFrameLength) {
+ in.skipBytes(in.readableBytes());
+ return null;
+ }
+ // 鍘婚櫎鏃犵敤鍓嶇紑鎶ユ枃
+ if (startMark != 0){
+ in.readerIndex(startMark);
+ in.discardReadBytes();
+ }
+ // 绮樺寘澶勭悊
+ in.markReaderIndex();
+ in.readerIndex(PackagePart.CONTENT_LENGTH.getStartIndex());
+ int pacTotalLen = PackagePart.START_SYMBOL.getLen()
+ + PackagePart.CONTENT_LENGTH.getLen()
+ + in.readShortLE()
+ + PackagePart.VALIDE_CODE.getLen()
+ ;
+ in.resetReaderIndex();
+ ByteBuf byteBuf = in.readSlice(pacTotalLen);
+
+ // 鐢熸垚鍜屽垵濮嬪寲娑堟伅鍖呰绫�
+ AgvPackage pac = AgvPackage.valueOfEmpty();
+ pac.setSourceBuff(byteBuf);
+
+ pac = analyzeProtocol(pac);
+ in.resetReaderIndex();
+
+ parseIMessageBody(pac);
+
+ return pac;
+ }
+
+ public static AgvPackage analyzeProtocol(AgvPackage pac){
+ ByteBuf byteBuf = pac.getSourceBuff();
+ PacHeader pacHeader = pac.getHeader();
+ // 鍞竴鏍囪瘑鐮�
+ byteBuf.readerIndex(PackagePart.UNIQUENO.getStartIndex());
+ byte[] bytes = new byte[PackagePart.UNIQUENO.getLen()];
+ byteBuf.readBytes(bytes);
+ Utils.reverse(bytes);
+ String uniqueno = String.valueOf(RadixTools.bytesToInt(bytes));
+ if (!Cools.isEmpty(uniqueno)) {
+ pacHeader.setUniqueNo(uniqueno);
+ byteBuf.resetReaderIndex();
+ } else {
+ return pac.setErrorPac(Boolean.TRUE).setPacErrorType(PacErrorType.PAC_ANALYZE_ERROR);
+ }
+ // 鑾峰彇鏍囪瘑绗�
+ byte startSymbol = byteBuf.readByte();
+ DirectionType direction = null;
+ if ((0xEE&0xFF) == (startSymbol&0xFF)) {
+ pacHeader.setStartSymbol(startSymbol);
+ direction = DirectionType.DOWN;
+ } else if ((0xAA&0xFF) == (startSymbol&0xFF)) {
+ pacHeader.setStartSymbol(startSymbol);
+ direction = DirectionType.UP;
+ } else {
+ return pac.setErrorPac(Boolean.TRUE).setPacErrorType(PacErrorType.PAC_ANALYZE_ERROR);
+ }
+ // 鑾峰彇鍗忚浣撻暱搴�
+ int contentLength = byteBuf.readShortLE();
+ if (contentLength >= 0) {
+ pacHeader.setContentLength(contentLength);
+ } else {
+ return pac.setErrorPac(Boolean.TRUE).setPacErrorType(PacErrorType.PAC_ANALYZE_ERROR);
+ }
+ // skip uniqueNo
+ byteBuf.readerIndex(byteBuf.readerIndex() + PackagePart.UNIQUENO.getLen());
+ // 鑾峰彇鏃堕棿鎴�
+ byteBuf.readerIndex(PackagePart.TIMESTAMP.getStartIndex());
+ int timestamp = byteBuf.readIntLE();
+ if (timestamp > 0) {
+ pacHeader.setTimestamp(timestamp);
+ } else {
+ return pac.setErrorPac(Boolean.TRUE).setPacErrorType(PacErrorType.PAC_ANALYZE_ERROR);
+ }
+ // 鑾峰彇鍛戒护鏍囪瘑
+ int commandByte = byteBuf.readByte() & 0xFF;
+ ProtocolType protocolType = ProtocolType.getByCode(commandByte, direction);
+ if (null != protocolType) {
+ pacHeader.setProtocolType(protocolType);
+ } else {
+ return pac.setErrorPac(Boolean.TRUE).setPacErrorType(PacErrorType.PAC_ANALYZE_ERROR);
+ }
+ // 鑾峰彇鍗忚浣�
+ if (contentLength > 0) {
+ ByteBuf body = byteBuf.readSlice(pac.getHeader().getContentLength() - (
+ + PackagePart.UNIQUENO.getLen()
+ + PackagePart.TIMESTAMP.getLen()
+ + PackagePart.COMMAND_MARK.getLen()
+ ));
+ if (null != body && body.readableBytes() >= 0) {
+ pac.getBody().setContent(body);
+ } else {
+ return pac.setErrorPac(Boolean.TRUE).setPacErrorType(PacErrorType.PAC_ANALYZE_ERROR);
+ }
+ }
+ // 鏍¢獙鐮�
+ if(byteBuf.readableBytes() == 2) {
+ pac.setValidCode(byteBuf.readUnsignedShortLE());
+ } else {
+ return pac.setErrorPac(Boolean.TRUE).setPacErrorType(PacErrorType.PAC_ANALYZE_ERROR);
+ }
+ return pac;
+ }
+
+ public static Boolean parseIMessageBody(AgvPackage pac){
+ String namespace = IMessageBody.class.getPackage().getName();
+
+ ProtocolType protocolType = pac.getHeader().getProtocolType();
+
+
+ if (null == protocolType) {
+
+ // 鏈煡鍖�
+ return Boolean.FALSE;
+ }
+
+ String className = namespace + ".AGV_" + Utils.zeroFill(Integer.toHexString(protocolType.getCode()).toUpperCase(), 2)
+ +"_"
+
+ + pac.getHeader().getProtocolType().getDirection().toString().toUpperCase();
+
+ Class<?> cls = null;
+ try {
+
+
+ cls = Class.forName(className);;
+
+ } catch (ClassNotFoundException e) {
+
+ log.error("MessageBodyHandler ClassNotFoundException", e);log.error("鎵句笉鍒版寚瀹氱被锛歿}", className);
+
+ return Boolean.FALSE;
+ }
+
+ Object obj = null;
+
+ if (null != cls) {
+
+
+ try {
+ obj = cls.newInstance();
+
+ } catch (ReflectiveOperationException reflectiveOperationException) {
+ log.error("MessageBodyHandler ReflectiveOperationException", reflectiveOperationException);
+
+ log.error("java鍙嶅皠鍒涘缓瀹炰緥澶辫触锛歿}", className);
+
+ // 銆傘�傘��
+ return Boolean.FALSE;
+ }
+
+
+ }
+
+ ByteBuf contentBuf = pac.getBody().getContent(); contentBuf.markReaderIndex(); // sign
+ // body.buf 灞炰簬鍒囩墖鑾峰彇锛� slice 涓� channel涓殑缂撳啿鍖� 涓哄悓涓� refenec
+
+
+
+ contentBuf.resetReaderIndex();
+
+ int len= contentBuf.readableBytes();
+
+ byte[] bytes = new byte[len];
+
+
+
+ pac.getBody().getContent().readBytes(bytes);
+
+
+
+ // 璇诲彇瀛楄妭鏁扮粍 ===>> 瀹為檯鎶ユ枃绫诲瀷
+ IMessageBody iMessageBody = null;
+
+ if (null != obj) {
+
+ if ( obj instanceof IMessageBody) {
+
+ iMessageBody = (IMessageBody) obj;
+
+
+ iMessageBody.readFromBytes(bytes);
+ }
+
+ }
+
+
+
+ pac.getBody().setMessageBody(iMessageBody); contentBuf.resetReaderIndex();
+
+ return true;
+ }
+
+ public static String encode(AgvPackage pac) {
+ ByteBuf out = Unpooled.buffer();
+
+ byte[] bodyBytes = pac.getBody().getMessageBody().writeToBytes(); // body
+
+ String uniqueNo = pac.getHeader().getUniqueNo();
+
+ byte[] uniquenoBytes = RadixTools.intToBytes(Integer.parseInt(pac.getHeader().getUniqueNo())); // uniqueno
+
+
+ int len = PackagePart.UNIQUENO.getLen() // len
+ + PackagePart.TIMESTAMP.getLen()
+ + PackagePart.COMMAND_MARK.getLen()
+ + bodyBytes.length;
+
+ out.writeByte(pac.getHeader().getStartSymbol()) // symbol
+ .writeShortLE(len)
+ .writeBytes(Utils.reverse(uniquenoBytes)) // uniqueno
+ .writeIntLE((int) (System.currentTimeMillis() / 1000)) // timestamp
+ .writeByte(pac.getHeader().getProtocolType().getCode()) // type
+ .writeBytes(bodyBytes) // body
+ .writeShort(pac.getValidCode()) // valid
+ ;
+
+ pac.setValidCode(ValidUtil.calculateValidByteFromBuff(out));
+ out.resetReaderIndex();
+
+ out.writerIndex(out.readableBytes() - 2);
+ out.writeShortLE(pac.getValidCode());
+
+ String hexStr = ByteBufUtil.hexDump(out).toUpperCase();
+
+// log.info("Agv [{}] 涓嬭 [{}] >>> {}", uniqueNo, pac.getHeader().getProtocolType().getDes(), hexStr);
+
+ return hexStr;
+ }
+
+
+ // 鑾峰彇鏍囪瘑浣嶄笅鏍�
+ public static int indexOfStartMark(ByteBuf inputBuffer){
+ int length = inputBuffer.writerIndex();
+ // 鎶ユ枃闀垮害鑷冲皯澶т簬2
+ if (length < 2) {
+ return -1;
+ }
+ int readerIndex = inputBuffer.readerIndex();
+ for(int i = readerIndex; i < length - 1; i ++) {
+ byte b1 = inputBuffer.getByte(i);
+ if ((0xEE&0xFF) == (b1&0xFF) || (0xAA&0xFF) == (b1&0xFF)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+}
diff --git a/zy-acs-gateway/src/main/resources/application.yml b/zy-acs-gateway/src/main/resources/application.yml
index bca5f95..b6b2f9b 100644
--- a/zy-acs-gateway/src/main/resources/application.yml
+++ b/zy-acs-gateway/src/main/resources/application.yml
@@ -28,7 +28,7 @@
logging:
file:
- path: /stock/out/rcs-gateway/logs
+ path: stock/out/rcs-gateway/logs
agv-tcp:
#tcp/ip鍗忚绔彛
--
Gitblit v1.9.1