From 14de918a79943e4961b09fa01ed320c6cad41f2e Mon Sep 17 00:00:00 2001
From: wjc <1243177876@qq.com>
Date: 星期三, 28 六月 2023 17:14:51 +0800
Subject: [PATCH] Revert "Revert "Merge branch 'hxb' into wjc""

---
 HDLLinkLocalSdk/src/main/java/com/hdl/sdk/link/core/protocol/LinkMessageDecoder.java |  323 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 323 insertions(+), 0 deletions(-)

diff --git a/HDLLinkLocalSdk/src/main/java/com/hdl/sdk/link/core/protocol/LinkMessageDecoder.java b/HDLLinkLocalSdk/src/main/java/com/hdl/sdk/link/core/protocol/LinkMessageDecoder.java
new file mode 100644
index 0000000..aa07c9d
--- /dev/null
+++ b/HDLLinkLocalSdk/src/main/java/com/hdl/sdk/link/core/protocol/LinkMessageDecoder.java
@@ -0,0 +1,323 @@
+package com.hdl.sdk.link.core.protocol;
+
+
+import com.hdl.sdk.link.common.utils.LogUtils;
+import com.hdl.sdk.link.common.event.EventDispatcher;
+import com.hdl.sdk.link.common.utils.ByteUtils;
+import com.hdl.sdk.link.core.bean.LinkPacket;
+import com.hdl.sdk.link.core.bean.LinkResponse;
+import com.hdl.sdk.link.core.utils.ByteBufferUtils;
+import com.hdl.sdk.link.core.utils.QueueUtils;
+import com.hdl.sdk.link.gateway.HDLLinkLocalGateway;
+import com.hdl.sdk.link.socket.bean.Packet;
+import com.hdl.sdk.link.socket.codec.ByteToMessageDecoder;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Created by Tong on 2021/9/22.
+ * link鍗忚绮樺寘鎷嗗寘
+ */
+public class LinkMessageDecoder extends ByteToMessageDecoder<LinkResponse> {
+
+    private static final String TAG=LinkMessageDecoder.class.getName();
+    //instance
+    private volatile static LinkMessageDecoder instance;
+
+    //getInstance
+    public static synchronized LinkMessageDecoder getInstance() {
+        if (instance == null) {
+            synchronized (LinkMessageDecoder.class) {
+                if (instance == null) {
+                    instance = new LinkMessageDecoder();
+                }
+            }
+        }
+        return instance;
+    }
+
+    /**
+     * 鎺ユ敹鏁版嵁缂撳啿鍖�
+     */
+    private final ByteBuffer byteBuffer;
+
+    private final byte[] head = "Topic:".getBytes();
+
+    public LinkMessageDecoder() {
+        byteBuffer = ByteBuffer.allocate(1024 * 200);//100K
+    }
+
+    /// <summary>
+    /// 鑾峰彇鍐呭闀垮害
+    /// </summary>
+    /// <param name="topMsgs"></param>
+    /// <returns></returns>
+    int getLenght(String[] topMsgs) {
+        try {
+            for (int i = 0; i < topMsgs.length; i++) {
+                String topMsg = topMsgs[i].trim();
+                if (topMsg.startsWith("Length:")) {
+                    return Integer.parseInt(topMsg.replace("Length:", "").trim());
+                }
+            }
+        } catch (Exception e) {
+            LogUtils.e("寮傚父鏁版嵁锛�" + topMsgs[0] + "\r\n" + topMsgs[1]);
+            return -1;
+        }
+        //鎵句笉鍒伴暱搴�
+        return -1;
+    }
+
+    /// <summary>
+    /// 鑾峰彇涓婚
+    /// </summary>
+    /// <param name="topMsgs"></param>
+    /// <returns></returns>
+    private String getTopic(String[] topMsgs) {
+        for (int i = 0; i < topMsgs.length; i++) {
+            String topMsg = topMsgs[i].trim();
+            if (topMsg.startsWith("Topic:")) {
+                return topMsg.replace("Topic:", "");
+            }
+        }
+        //鎵句笉鍒颁富棰�
+        return null;
+    }
+
+    /**
+     * 鑾峰彇鏁版嵁鐨勫紑濮嬩綅缃�
+     *
+     * @return 鏁版嵁浣嶇殑寮�濮嬬储寮�
+     */
+    int getBodyIndex() {
+        byte r = (byte) '\r';
+        byte n = (byte) '\n';
+        for (int i = 0; i < byteBuffer.position(); i++) {
+            //鎵惧嚭鏁版嵁鍐呭鍓嶉潰鐨勪袱涓崲琛�
+            if (3 <= i && byteBuffer.get(i - 3) == r && byteBuffer.get(i - 2) == n && byteBuffer.get(i - 1) == r && byteBuffer.get(i) == n) {
+                //鍓╀綑鐨勬暟鎹�
+                return i + 1;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * 鑾峰彇澶撮儴鏁版嵁
+     *
+     * @return
+     */
+    String getHeader() {
+        int bodyIndex = getBodyIndex();
+        if (bodyIndex < 0) {
+            //娌℃湁鎵惧埌澶撮儴鏁版嵁
+            return null;
+        } else {
+            byte bodyBytes[] = ByteBufferUtils.copyBytes(byteBuffer, bodyIndex);
+            return new String(bodyBytes);
+        }
+    }
+
+    /**
+     * 鑾峰彇鏁版嵁鍐呭
+     *
+     * @param lenght
+     * @return
+     */
+    byte[] getBody(int index, int lenght) {
+        //鏄惁宸茬粡鑾峰彇瀹屾暣鎵�鏈夌殑鏁版嵁
+        byte[] bodyBytes = new byte[lenght];
+        if (index < 0 || byteBuffer.position() < index + lenght) {
+            //褰撳墠鏁版嵁杩樻病鏈夋帴鏀跺畬鎴�
+            return null;
+        }
+
+        for (int i = 0; i < bodyBytes.length; i++) {
+            bodyBytes[i] = byteBuffer.get(index + i);
+        }
+        return bodyBytes;
+    }
+
+
+    /**
+     * 杩欒竟澶勭悊浜嗙紦瀛樻暟鎹矘鍖呯殑鎯呭喌锛屾瘡娆¤姹傞兘闇�瑕佸惂褰撳墠瀹屾暣鐨勬枃浠堕櫎鍘�   浠ヤ究浜庝笅娆$殑杩斿洖
+     * tempList鐢ㄤ簬瀛樺偍澶氫綑鐨勬暟鎹�
+     * contentList鐢ㄤ簬鏈鏁版嵁鐨勫瓨鍌紙鍙戦�佺粰璁㈤槄鐨勬暟鎹級
+     */
+    byte[] geBody() {
+        int len = 3 + 4 + 4 + ((byteBuffer.get(7) & 0xFF) * 256 * 256 * 256) + ((byteBuffer.get(8) & 0xFF) * 256 * 256) + ((byteBuffer.get(9) * 256) & 0xFF) + (byteBuffer.get(10) & 0xFf);
+        byte[] bodyBytes = new byte[len];
+        for (int i = 0; i < len; i++) {
+            bodyBytes[i] = byteBuffer.get(i);
+        }
+
+        int endIndex = byteBuffer.position();
+        byteBuffer.clear();
+        for (int i = len; i < endIndex; i++) {
+            byteBuffer.put(byteBuffer.get(i));
+        }
+        return bodyBytes;
+    }
+
+    /**
+     * 绉婚櫎鍙兘瀛樺湪鐨勬棤鏁堟暟鎹�
+     */
+    void removeInVoidBytes() {
+        int index = 0;
+        boolean isMatch = false;
+        for (; index < byteBuffer.position() - head.length; index++) {
+            isMatch = true;
+            for (int j = 0, k = 0; j < head.length; j++, k++) {
+                if (head[j] != byteBuffer.get(index + k)) {
+                    isMatch = false;
+                    break;
+                }
+            }
+            if (isMatch) {
+                break;
+            }
+        }
+
+        if (0 < index && isMatch) {
+            int endIndex = byteBuffer.position();
+            byteBuffer.clear();
+            for (int i = index; i < endIndex; i++) {
+                byteBuffer.put(byteBuffer.get(i));
+            }
+        }
+    }
+
+    /**
+     * 绉婚櫎鍒版寚瀹氫綅缃墠闈㈢殑鏁版嵁
+     *
+     * @param position 鎸囧畾浣嶇疆
+     */
+    void remove(int position) {
+        int endIndex = byteBuffer.position();
+        byteBuffer.clear();
+        for (int i = position; i < endIndex; i++) {
+            byteBuffer.put(byteBuffer.get(i));
+        }
+    }
+
+    void fileManger(int commandAck, byte[] recevieBytes) {
+        String topic = "65531_" + commandAck;
+        LinkResponse response = new LinkResponse();
+        response.setTopic(topic);
+        response.setByteData(recevieBytes);
+        EventDispatcher.getInstance().post(response.getTopic(), response);
+    }
+
+    int bytes2int(byte[] bytes) {
+        int result = 0;
+        if (bytes.length == 2) {
+            int c = (bytes[0] & 0xff) << 8;
+            int d = (bytes[1] & 0xff);
+            result = c | d;
+        } else if (bytes.length == 4) {
+            return bytes[3] & 0xFF | //
+                    (bytes[2] & 0xFF) << 8 | //
+                    (bytes[1] & 0xFF) << 16 | //
+                    (bytes[0] & 0xFF) << 24; //
+        }
+        return result;
+    }
+
+    public String byte2hex(byte[] bytes) {
+        StringBuilder sb = new StringBuilder();
+        String tmp = null;
+        for (byte b : bytes) {
+            //灏嗘瘡涓瓧鑺備笌0xFF杩涜涓庤繍绠楋紝鐒跺悗杞寲涓�10杩涘埗锛岀劧鍚庡�熷姪浜嶪nteger鍐嶈浆鍖栦负16杩涘埗
+            tmp = Integer.toHexString(0xFF & b);
+            if (tmp.length() == 1) {
+                tmp = "0" + tmp;
+            }
+            sb.append(tmp + " ");
+        }
+        return sb.toString();
+    }
+
+    @Override
+    protected synchronized LinkResponse decoder(Packet packet) {
+        try {
+            if (null == packet) {
+                return null;
+            }
+            byteBuffer.put(packet.getBytes());
+        } catch (Exception e) {
+            LogUtils.e("鎺ユ敹鍒版暟鎹紓甯�:\r\n" + e.getMessage());
+            byteBuffer.flip();
+            byteBuffer.clear();
+        }
+        try {
+            //濡傛灉澶氭潯鍛戒护鎵撳寘鍦ㄤ竴鏉℃暟鎹腑锛岄兘闇�瑕佸鐞嗗畬
+            while (true) {
+                if (byteBuffer.position() > 2) {//鍒ゆ柇鏄惁鏄枃浠跺鐞嗛�氱煡 wxr
+                    byte[] topBytes = new byte[3];
+                    topBytes[0] = byteBuffer.get(0);
+                    topBytes[1] = byteBuffer.get(1);
+                    topBytes[2] = byteBuffer.get(2);
+                    if (new String(topBytes).equals("hex")) {
+                        //TODO 杩欏潡浠g爜缁熶竴绉诲嚭鍏跺畠鍦版柟澶勭悊
+                        byte[] commandBytes = ByteBufferUtils.copyBytes(byteBuffer, 5, 2);
+                        int command = bytes2int(commandBytes);
+                        byte[] submitBytes = geBody();
+                        if (command == 258 || command == 260 || command == 261) {
+                            //璇诲彇椹卞姩鍒楄〃鍝嶅簲 ||椹卞姩瀹夎鐢宠鍝嶅簲
+                            if (submitBytes.length > 11) {
+                                byte[] rangeBytes = ByteUtils.copyBytes(submitBytes, 11, submitBytes.length - 11);
+                                fileManger(command, rangeBytes);
+                            } else {
+                                //鏂逛究闂鎺掓煡
+                                fileManger(command, submitBytes);
+                            }
+                        } else {
+                            //缁欑妗′娇鐢�  鍚庨潰鐨勪笟鍔℃渶濂介兘鍦ㄨ繖杈瑰鐞� 涓嶇劧浼氶�犳垚涓氬姟鍒嗘暎
+                            fileManger(command, submitBytes);
+                        }
+                        continue;
+                    }
+                }
+                removeInVoidBytes();//绉婚櫎鍙兘瀛樺湪鐨勬棤鏁堟暟鎹�
+
+                //澶撮儴鏁版嵁
+                String header = getHeader();
+
+                if (header == null) {
+                    break;
+                }
+                String[] topMsgs = header.split("\r\n");
+
+                String topic = getTopic(topMsgs);
+                int lenght = getLenght(topMsgs);
+                if (topic == null || lenght <= 0) {
+                    //鑾峰彇涓嶅埌涓婚鎴栬�呭ご閮ㄦ暟鎹繕娌℃湁鎺ユ敹瀹屾垚
+                    break;
+                }
+
+                int bodyIndex = getBodyIndex();
+                //鏄惁宸茬粡鑾峰彇瀹屾暣鎵�鏈夌殑鏁版嵁
+                byte[] body = getBody(bodyIndex, lenght);
+
+                if (body == null) {
+                    //褰撳墠鏁版嵁杩樻病鏈夋帴鏀跺畬鎴�
+                    break;
+                }
+
+                remove(bodyIndex + lenght);
+
+                if (topic.contains("heartbeat_reply")) {
+                    if (packet.getSocket() != null) {
+                        packet.getSocket().setSoTimeout(10 * 1000);
+                    }
+                    continue;
+                }
+
+                QueueUtils.getInstance().add(new LinkPacket(topic, body));
+            }
+        } catch (Exception ee) {
+            LogUtils.e("澶勭悊鎺ユ敹鐨勬暟鎹紓甯�:\r\n" + ee.getMessage());
+        }
+        return null;
+    }
+}

--
Gitblit v1.8.0