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