From 1560f3063ca90d41c0717f8ed6e1fb00fde64776 Mon Sep 17 00:00:00 2001
From: luxiaotao1123 <t1341870251@163.com>
Date: 星期一, 12 八月 2024 15:56:56 +0800
Subject: [PATCH] #

---
 app/src/main/java/com/example/agvcontroller/protocol/PacHeader.java       |   98 ++++++++++
 app/src/main/java/com/example/agvcontroller/protocol/AGV_02_DOWN.java     |   47 +++++
 app/src/main/java/com/example/agvcontroller/protocol/AgvPackage.java      |  157 +++++++++++++++++
 app/src/main/java/com/example/agvcontroller/protocol/ProtocolEncoder.java |   89 +++++++++
 app/src/main/java/com/example/agvcontroller/protocol/CRCUtils.java        |   41 ++++
 app/src/main/java/com/example/agvcontroller/protocol/ProtocolUtils.java   |   86 +++++++++
 app/src/main/java/com/example/agvcontroller/protocol/IMessageBody.java    |   11 +
 7 files changed, 529 insertions(+), 0 deletions(-)

diff --git a/app/src/main/java/com/example/agvcontroller/protocol/AGV_02_DOWN.java b/app/src/main/java/com/example/agvcontroller/protocol/AGV_02_DOWN.java
new file mode 100644
index 0000000..74bde9d
--- /dev/null
+++ b/app/src/main/java/com/example/agvcontroller/protocol/AGV_02_DOWN.java
@@ -0,0 +1,47 @@
+package com.zy.acs.common.domain.protocol;
+
+import com.zy.acs.common.utils.Utils;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.Serializable;
+
+/**
+ * 鍔ㄤ綔鍛戒护鍖�
+ * Created by vincent on 2023/3/21
+ */
+@Data
+public class AGV_02_DOWN implements IMessageBody, Serializable {
+
+    private static final long serialVersionUID = 1664188062202647371L;
+
+    @Override
+    public byte[] writeToBytes() {
+        String serialNo = Utils.zeroFill(this.serialNo, 16);
+        byte[] serialNoBytes = Utils.reverse(serialNo.getBytes());
+        byte cmdCodeByte = (byte) this.getCmdCode();
+        byte valByte = (byte) this.getVal();
+
+        byte[] cmdBodyBytes = commandBody.writeToBytes();
+
+        return Utils.merge(serialNoBytes, cmdCodeByte, valByte, cmdBodyBytes);
+    }
+
+    @Override
+    public void readFromBytes(byte[] messageBodyBytes) {
+
+    }
+
+    // 娴佹按鍙� - 16
+    private String serialNo;
+
+    // 鍛戒护鐮�
+    private int cmdCode;
+
+    // 灞炴�у��
+    private int val;
+
+    // 鍔ㄤ綔鍙傛暟
+    private ICommandBody commandBody;
+
+}
diff --git a/app/src/main/java/com/example/agvcontroller/protocol/AgvPackage.java b/app/src/main/java/com/example/agvcontroller/protocol/AgvPackage.java
new file mode 100644
index 0000000..e50fa82
--- /dev/null
+++ b/app/src/main/java/com/example/agvcontroller/protocol/AgvPackage.java
@@ -0,0 +1,157 @@
+package com.zy.acs.gateway.domain;
+
+import com.core.common.Cools;
+import com.zy.acs.gateway.constant.AgvConstant;
+import com.zy.acs.gateway.constant.PacErrorType;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+
+import java.util.Objects;
+
+/**
+ * AGV鎶ユ枃妯″瀷
+ * Created by vincent on 2023/3/10
+ */
+public class AgvPackage implements PackageSupport {
+
+    /**
+     * 婧愭暟鎹寘缂撳啿鍖�(寮曠敤)
+     */
+    private ByteBuf sourceBuff;
+
+    /**
+     * 鍘熷娑堟伅瀵瑰簲鐨�16杩涘埗瀛楃涓�
+     */
+    private String sourceHexStr;
+
+    /**
+     * 娑堟伅澶撮儴
+     */
+    private PacHeader header;
+
+    /**
+     * 娑堟伅浣�
+     */
+    private PacBody body;
+
+    /**
+     * 娑堟伅鐨勬牎姝g爜
+     */
+    private int validCode;
+
+    /**
+     * 鏄惁涓烘牎楠屽紓甯稿寘
+     */
+    private boolean errorPac;
+
+    /**
+     * 鏍¢獙寮傚父绫诲瀷
+     */
+    private PacErrorType pacErrorType;
+
+    public static AgvPackage valueOfEmpty() {
+        AgvPackage agvPackage = new AgvPackage();
+        agvPackage.setHeader(new PacHeader())
+                .setBody(new PacBody())
+                .setValidCode((short) 0)
+                .setErrorPac(false);
+        return agvPackage;
+    }
+
+    public String toLogString() {
+        StringBuilder pacSb = new StringBuilder();
+        pacSb.append("AGV(").append(getHeader().getUniqueNo()).append(")")
+            .append("涓婁紶")
+            .append("[").append(getHeader().getProtocolType().getDes()).append("]娑堟伅.")
+            .append("鍘熷娑堟伅[").append(getSourceHexStr()).append("]");
+        return pacSb.toString();
+    }
+
+    public ByteBuf getSourceBuff() {
+        // 鍥犱负澶勭悊buffer鏃讹紝鎬绘槸甯屾湜鎷垮埌涓�涓噸缃簡readerIndex鐨刡uf
+        if (Objects.nonNull(this.sourceBuff)) {
+            this.sourceBuff.resetReaderIndex();
+        }
+        return this.sourceBuff;
+    }
+
+    public AgvPackage setSourceBuff(ByteBuf sourceBuff) {
+        this.sourceBuff = sourceBuff;
+        if (Cools.isEmpty(this.sourceHexStr)) {
+            this.sourceBuff.resetReaderIndex();
+            this.sourceHexStr = ByteBufUtil.hexDump(this.sourceBuff).toUpperCase();
+            this.sourceBuff.resetReaderIndex();
+        }
+        return this;
+    }
+
+    public PacHeader getHeader() {
+        return header;
+    }
+
+    public AgvPackage setHeader(PacHeader header) {
+        this.header = header;
+        return this;
+    }
+
+    public PacBody getBody() {
+        return body;
+    }
+
+    public AgvPackage setBody(PacBody body) {
+        this.body = body;
+        return this;
+    }
+
+    public int getValidCode() {
+        return validCode;
+    }
+
+    public AgvPackage setValidCode(int validCode) {
+        this.validCode = validCode;
+        return this;
+    }
+
+    public boolean isErrorPac() {
+        return errorPac;
+    }
+
+    public AgvPackage setErrorPac(boolean errorPac) {
+        this.errorPac = errorPac;
+        return this;
+    }
+
+    public String getSourceHexStr() {
+        return sourceHexStr;
+    }
+
+    public AgvPackage setSourceHexStr(String sourceHexStr) {
+        this.sourceHexStr = sourceHexStr;
+        return this;
+    }
+
+    public PacErrorType getPacErrorType() {
+        return pacErrorType;
+    }
+
+    public AgvPackage setPacErrorType(PacErrorType pacErrorType) {
+        this.pacErrorType = pacErrorType;
+        return this;
+    }
+
+    public ByteBuf convert(ByteBuf byteBuf){
+        byteBuf.writeByte(this.getHeader().getStartSymbol())
+                .writeShort(this.getHeader().getContentLength())
+                .writeByte(this.getHeader().getProtocolType().getCode())
+                .writeBytes(this.getHeader().getUniqueNo().getBytes(AgvConstant.CHARSET_GBK))
+                .writeByte(this.getHeader().getEncryptType().getCode())
+                .writeBytes(this.getBody().getContent())
+                .writeByte(this.getValidCode());
+        // 璁$畻骞惰缃牎楠岀爜
+//        this.setValidCode(ValidUtil.caculateValidByteFromBuff(byteBuf));
+        byteBuf.resetReaderIndex();
+        byteBuf.writerIndex(byteBuf.readableBytes() - 1).writeByte(this.getValidCode());
+        return byteBuf;
+    }
+
+}
diff --git a/app/src/main/java/com/example/agvcontroller/protocol/CRCUtils.java b/app/src/main/java/com/example/agvcontroller/protocol/CRCUtils.java
new file mode 100644
index 0000000..a5047c8
--- /dev/null
+++ b/app/src/main/java/com/example/agvcontroller/protocol/CRCUtils.java
@@ -0,0 +1,41 @@
+package com.zy.acs.gateway.utils;
+
+/**
+ * CRC16寰幆鍐椾綑鏍¢獙鐮�
+ * Created by vincent on 2023/3/13
+ */
+public class CRCUtils {
+
+    /**
+     * 涓�涓瓧鑺傚崰 8浣�
+     */
+    private static final int BITS_OF_BYTE = 8;
+
+    /**
+     * 澶氶」寮�
+     */
+    private static final int POLYNOMIAL = 0XA001;
+
+    /**
+     * CRC瀵勫瓨鍣ㄩ粯璁ゅ垵濮嬪��
+     */
+    private static final int INITIAL_VALUE = 0XFFFF;
+
+    /**
+     * CRC16 缂栫爜
+     * @param bytes 缂栫爜鍐呭
+     * @return 缂栫爜缁撴灉
+     */
+    public static int crc16(byte[] bytes) {
+        int res = INITIAL_VALUE;
+        for (byte data : bytes) {
+            // 鎶奲yte杞崲鎴恑nt鍚庡啀璁$畻
+            res = res ^ (data & 0XFF);
+            for (int i = 0; i < BITS_OF_BYTE; i++) {
+                res = (res & 0X0001) == 1 ? (res >> 1) ^ POLYNOMIAL : res >> 1;
+            }
+        }
+        return res;
+    }
+
+}
diff --git a/app/src/main/java/com/example/agvcontroller/protocol/IMessageBody.java b/app/src/main/java/com/example/agvcontroller/protocol/IMessageBody.java
new file mode 100644
index 0000000..a6a6d90
--- /dev/null
+++ b/app/src/main/java/com/example/agvcontroller/protocol/IMessageBody.java
@@ -0,0 +1,11 @@
+package com.zy.acs.common.domain.protocol;
+
+import java.io.Serializable;
+
+public interface IMessageBody extends Serializable {
+
+    byte[] writeToBytes();
+
+    void readFromBytes(byte[] messageBodyBytes);
+
+}
diff --git a/app/src/main/java/com/example/agvcontroller/protocol/PacHeader.java b/app/src/main/java/com/example/agvcontroller/protocol/PacHeader.java
new file mode 100644
index 0000000..a41be16
--- /dev/null
+++ b/app/src/main/java/com/example/agvcontroller/protocol/PacHeader.java
@@ -0,0 +1,98 @@
+package com.zy.acs.gateway.domain;
+
+import com.zy.acs.gateway.constant.EncryType;
+import com.zy.acs.gateway.constant.ProtocolType;
+import lombok.Data;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+/**
+ * 鍗忚澶�
+ * Created by vincent on 2019-04-03
+ */
+@Data
+public class PacHeader {
+
+    /**
+     * 璧峰绗�
+     * 鍥哄畾涓�"0xEE || 0xAA"
+     */
+    private byte startSymbol;
+
+    /**
+     * 鏁版嵁鍗曞厓闀垮害
+     */
+    private int contentLength;
+
+    /**
+     * 鍞竴鏍囪瘑鐮�
+     */
+    private String uniqueNo;
+
+    /**
+     * 鏃堕棿鎴�
+     */
+    private int timestamp;
+
+    /**
+     * 鍛戒护鏍囪瘑
+     */
+    private ProtocolType protocolType;
+
+    /**
+     * 娴佹按鍙�
+     */
+    private String serialNum;
+
+    /**
+     * 鏁版嵁鍗曞厓鍔犲瘑鏂瑰紡
+     */
+    private EncryType encryptType;
+
+
+    public PacHeader setStartSymbol(Byte startSymbol) {
+        this.startSymbol = startSymbol;
+        return this;
+    }
+
+    public PacHeader setProtocolType(ProtocolType protocolType) {
+        this.protocolType = protocolType;
+        return this;
+    }
+
+    public PacHeader setTimestamp(Integer timestamp) {
+        this.timestamp = timestamp;
+        return this;
+    }
+
+    public PacHeader setSerialNum(String serialNum) {
+        this.serialNum = serialNum;
+        return this;
+    }
+
+    public PacHeader setUniqueNo(String uniqueNo) {
+        this.uniqueNo = uniqueNo;
+        return this;
+    }
+
+    public PacHeader setEncryptType(EncryType encryptType) {
+        this.encryptType = encryptType;
+        return this;
+    }
+
+    public PacHeader setContentLength(int contentLength) {
+        this.contentLength = contentLength;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this)
+                .append("startSymbol", startSymbol)
+                .append("contentLength", contentLength)
+                .append("uniqueNo", uniqueNo)
+                .append("timestamp", timestamp)
+                .append("protocolType", protocolType.getDes())
+                .append("serialNum", serialNum)
+                .toString();
+    }
+}
diff --git a/app/src/main/java/com/example/agvcontroller/protocol/ProtocolEncoder.java b/app/src/main/java/com/example/agvcontroller/protocol/ProtocolEncoder.java
new file mode 100644
index 0000000..04a396a
--- /dev/null
+++ b/app/src/main/java/com/example/agvcontroller/protocol/ProtocolEncoder.java
@@ -0,0 +1,89 @@
+package com.zy.acs.gateway.handler.coder;
+
+import com.core.common.RadixTools;
+import com.zy.acs.common.utils.Utils;
+import com.zy.acs.gateway.config.SystemProperties;
+import com.zy.acs.gateway.constant.PackagePart;
+import com.zy.acs.gateway.domain.AgvPackage;
+import com.zy.acs.gateway.utils.ValidUtil;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToByteEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * 缂栫爜鍣�
+ * 姝よВ鐮佸櫒灏嗕細鐢熸垚鏍¢獙鐮�
+ * 澶勭悊鏂瑰紡: 寮傛垨鍜�
+ * Created by vincent on 2019-04-02
+ */
+@Component
+@ChannelHandler.Sharable
+public class ProtocolEncoder extends MessageToByteEncoder<Object> {
+
+    private static final Logger log = LoggerFactory.getLogger(ProtocolEncoder.class);
+
+    @Autowired
+    private SystemProperties systemProperties;
+
+    @Override
+    protected void encode(ChannelHandlerContext ctx, Object obj, ByteBuf out) {
+
+        if (obj instanceof ByteBuf){
+            out.writeBytes((ByteBuf) obj);
+
+        } else if (obj instanceof byte[]){
+            out.writeBytes((byte[]) obj);
+
+        } else if (obj instanceof AgvPackage){
+
+            AgvPackage pac = (AgvPackage)obj;
+
+
+
+            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());
+
+
+            if (systemProperties.isPrintPacLog()){
+                log.info("Agv [{}] 涓嬭 [{}] >>> {}", uniqueNo, pac.getHeader().getProtocolType().getDes(), ByteBufUtil.hexDump(out).toUpperCase());
+            }
+
+        }
+
+
+    }
+
+// EE | 11 00 | 01 00 00 00 | 0C AB 12 64 | F0  | 01 00 | 01 01 | 00 00 00 00 | 4C F7
+// #  | len   | uniqueno    | timestamp   | cmd | content                     | crc
+
+}
diff --git a/app/src/main/java/com/example/agvcontroller/protocol/ProtocolUtils.java b/app/src/main/java/com/example/agvcontroller/protocol/ProtocolUtils.java
new file mode 100644
index 0000000..2ea178b
--- /dev/null
+++ b/app/src/main/java/com/example/agvcontroller/protocol/ProtocolUtils.java
@@ -0,0 +1,86 @@
+package com.zy.acs.gateway.utils;
+
+import com.zy.acs.common.domain.AgvProtocol;
+import com.zy.acs.common.domain.protocol.IMessageBody;
+import com.zy.acs.gateway.constant.ProtocolPojoType;
+import com.zy.acs.gateway.constant.ProtocolType;
+import com.zy.acs.gateway.domain.AgvPackage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Created by vincent on 2019-04-03
+ */
+public class ProtocolUtils {
+
+    private static final Logger log = LoggerFactory.getLogger(ProtocolUtils.class);
+
+    // 涓嬭鍗忚鎶ユ枃缁勮
+    public static AgvPackage installDownProtocol(AgvProtocol protocol){
+
+
+        ProtocolPojoType protocolPojo = ProtocolPojoType.query(protocol.getMessageBody().getClass());
+
+        assert protocolPojo !=   null;
+
+        AgvPackage ackPackage = AgvPackage.valueOfEmpty();
+        ackPackage.getHeader()
+                .setStartSymbol((byte)0xEE)
+                .setContentLength(0)
+                .setUniqueNo(protocol.getAgvNo())
+                .setTimestamp(protocol.getTimestamp())
+                .setProtocolType(protocolPojo.protocolType)
+        ;
+
+        ackPackage.getBody().setMessageBody(protocol.getMessageBody());
+
+        return ackPackage;
+
+    }
+
+    // 涓嬭鍗忚鎶ユ枃缁勮
+    public static AgvPackage installDownProtocol(String uniqueNo, ProtocolType protocolType){
+
+
+        AgvPackage ackPackage = AgvPackage.valueOfEmpty();
+        ackPackage.getHeader()
+                .setStartSymbol((byte)0xEE)
+                .setContentLength(0)
+                .setUniqueNo(uniqueNo)
+                .setTimestamp((int)System.currentTimeMillis()/1000)
+                .setProtocolType(protocolType)
+        ;
+
+        ProtocolPojoType protocolPojo = ProtocolPojoType.query(protocolType);
+
+
+        assert protocolPojo != null;
+
+
+        IMessageBody iMessageBody = null;
+
+        try {
+
+            iMessageBody = protocolPojo.clazz.newInstance();
+        } catch (ReflectiveOperationException reflectiveOperationException) {
+
+
+            log.error("MessageBodyHandler ReflectiveOperationException", reflectiveOperationException);
+
+            log.error("java鍙嶅皠鍒涘缓瀹炰緥澶辫触锛歿}", protocolPojo.clazz.getName());
+
+            return null;
+        }
+
+
+
+        ackPackage.getBody().setMessageBody(iMessageBody);
+
+
+
+        return ackPackage;
+    }
+
+
+
+}

--
Gitblit v1.9.1