From 0188dee359636723190f0f67a6b674b7b08f7bef Mon Sep 17 00:00:00 2001
From: hxb <hxb@hdlchina.com.cn>
Date: 星期一, 21 三月 2022 09:55:01 +0800
Subject: [PATCH] 增加判断json数据格式

---
 HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java |  275 +++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 217 insertions(+), 58 deletions(-)

diff --git a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java
index 4cc8a8f..edb326e 100644
--- a/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java
+++ b/HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java
@@ -1,6 +1,13 @@
 package com.hdl.sdk.connect.protocol;
 
 
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.util.Log;
+
+import androidx.annotation.RequiresApi;
+
+import com.google.gson.internal.bind.DateTypeAdapter;
 import com.hdl.sdk.common.utils.LogUtils;
 import com.hdl.sdk.connect.config.HDLLinkConfig;
 import com.hdl.sdk.common.event.EventDispatcher;
@@ -11,6 +18,7 @@
 import com.hdl.sdk.socket.codec.ByteToMessageDecoder;
 
 import java.util.ArrayList;
+import java.util.Base64;
 import java.util.List;
 
 /**
@@ -22,77 +30,228 @@
     private final List<Byte> bytes;
 
     private final byte[] head = "Topic:".getBytes();
-    private final byte[] body = "\r\n\r\n".getBytes();
+//    private final byte[] body = "\r\n\r\n".getBytes();
 
     public LinkMessageDecoder() {
         this.bytes = new ArrayList<>();
     }
 
-    @Override
-    protected LinkResponse decoder(Object msg) throws Exception {
-        LinkResponse response = new LinkResponse();
-        if (msg instanceof byte[]) {
-            //瑙f瀽娴�
-            byte[] data = (byte[]) msg;
-            bytes.addAll(ByteUtils.toByteList(data));
-
-            byte[] byteArray = ByteUtils.toByteArray(bytes);
-            int headIndex = ByteUtils.getByteIndexOf(byteArray, head);
-            if (headIndex > 0) {
-                //绉诲姩鍒癶ead 寮�濮嬩綅缃�
-                bytes.subList(0, headIndex).clear();
-                byteArray = ByteUtils.toByteArray(bytes);
+    /// <summary>
+    /// 鑾峰彇鍐呭闀垮害
+    /// </summary>
+    /// <param name="topMsgs"></param>
+    /// <returns></returns>
+    int getLenght(String[] topMsgs) {
+        for (int i = 0; i < topMsgs.length; i++) {
+            String topMsg = topMsgs[i].trim();
+            if (topMsg.startsWith("Length:")) {
+                return Integer.parseInt(topMsg.replace("Length:", ""));
             }
+        }
+        //鎵句笉鍒伴暱搴�
+        return -1;
+    }
 
-            int bodyIndex = ByteUtils.getByteIndexOf(byteArray, body);
-            if (bodyIndex < 0) {
-                //澶撮儴鏈幏鍙栧畬鎴�
-                return null;
+    /// <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:", "");
             }
-            int bodyStartIndex = bodyIndex + body.length;
+        }
+        //鎵句笉鍒颁富棰�
+        return null;
+    }
 
-            //瑙f瀽澶撮儴
-            ProtocolParse parse = new ProtocolParse(byteArray);
-            response.setTopic(parse.getTopic());
+    /**
+     * 鑾峰彇鏁版嵁鐨勫紑濮嬩綅缃�
+     *
+     * @param arrayList 鎺ユ敹鍒扮殑鎵�鏈夋暟鎹�
+     * @return 鏁版嵁浣嶇殑寮�濮嬬储寮�
+     */
+    int getDataIndex(List<Byte> arrayList) {
+        byte r = (byte) '\r';
+        byte n = (byte) '\n';
+        for (int i = 0; i < arrayList.size(); i++) {
+            //鎵惧嚭鏁版嵁鍐呭鍓嶉潰鐨勪袱涓崲琛�
+            if (3 <= i && arrayList.get(i - 3) == r && arrayList.get(i - 2) == n && arrayList.get(i - 1) == r && arrayList.get(i) == n) {
+                //鍓╀綑鐨勬暟鎹�
+                return i + 1;
+            }
+        }
+        return -1;
+    }
 
-            int bodyLength = parse.getLength();
-            if (bodyLength > 0) {
-                if (byteArray.length >= bodyLength + bodyStartIndex) {
-                    byte[] body = ByteUtils.getRangeBytes(bytes, bodyStartIndex, bodyStartIndex + bodyLength);
+    void initReceiveData(List<Byte> list) {
 
-                    if (HDLLinkConfig.getInstance().ifNeedEncrypt(response.getTopic())) {
-                        //闇�瑕佽В瀵�
-                        byte[] bodyBytes = AesUtil.aesDecrypt(body, HDLLinkConfig.getInstance().getLocalSecret());
-//                        byte[] bodyBytes = AESUtils.decryptAES(body,AuthenticateConfig.getInstance().getLocalSecret());
-                        if (bodyBytes != null) {
-                            response.setData(new String(bodyBytes, "utf-8"));
-//                            LogUtils.i("TAG", "瑙e瘑 涓婚锛�"+response.getTopic()+ " body: "+response.getData());
-                        } else {
-                            //瑙e瘑澶辫触锛岃繑鍥炲師鏁版嵁
-                            response.setData(new String(body, "utf-8"));
-                            LogUtils.e( "瑙e瘑澶辫触");
-                        }
-
-                    } else {
-                        response.setData(new String(body, "utf-8"));
-                    }
-
-                    if (byteArray.length >= bodyLength + bodyStartIndex) {
-                        //淇濆瓨浣欑暀
-                        byte[] remaining = ByteUtils.getRangeBytes(bytes, bodyStartIndex + bodyLength, byteArray.length);
-                        bytes.clear();
-                        for (byte b : remaining) {
-                            bytes.add(b);
-                        }
-                    }
-                    //瑙f瀽瀹屾垚,topic鍙戦�佷竴娆�
-                    EventDispatcher.getInstance().post(response.getTopic(), response);
-                    return response;
+        int index = 0;
+        boolean isMatch = false;
+        for (; index < list.size() - head.length; index++) {
+            isMatch = true;
+            for (int j = 0, k = 0; j < head.length; j++, k++) {
+                if (head[j] != list.get(index + k)) {
+                    isMatch = false;
+                    break;
                 }
-            } else if (bodyLength == 0) {
-                //body涓虹┖
-                return response;
             }
+            if (isMatch) {
+                break;
+            }
+        }
+
+        if (0 < index && isMatch) {
+            List<Byte> tempList = new ArrayList<Byte>();
+            for (int i = index; i < list.size(); i++) {
+                tempList.add(list.get(i));
+            }
+
+            list.clear();
+            for(int i=0;i<tempList.size();i++){
+                list.add(tempList.get(i));
+            }
+        }
+    }
+
+
+    @Override
+    protected synchronized LinkResponse decoder(Object msg,String ipaddress) throws Exception {
+        if (msg instanceof byte[]) {
+            bytes.addAll(ByteUtils.toByteList((byte[]) msg));
+            //濡傛灉澶氭潯鍛戒护鎵撳寘鍦ㄤ竴鏉℃暟鎹腑锛岄兘闇�瑕佸鐞嗗畬
+            while (true) {
+                initReceiveData(bytes);
+                byte[] recevieBytes = ByteUtils.toByteArray(bytes);
+                String data = new String(recevieBytes);
+
+                String[] topMsgs = data.split("\r\n");
+
+                String topic = getTopic(topMsgs);
+                if (topic == null) {
+                    break;
+                }
+
+                int lenght = getLenght(topMsgs);
+
+                if (lenght <= 0) {
+                    //澶撮儴鏁版嵁杩樻病鏈夋帴鏀跺畬鎴�
+                    break;
+                }
+                //鏄惁宸茬粡鑾峰彇瀹屾暣鎵�鏈夌殑鏁版嵁
+                byte[] body = new byte[lenght];
+                int index = getDataIndex(bytes);
+                if (bytes.size() < index + lenght) {
+                    //褰撳墠鏁版嵁杩樻病鏈夋帴鏀跺畬鎴�
+                    break;
+                }
+                //澶嶅埗鍑篵ody鏁版嵁
+                System.arraycopy(recevieBytes, index, body, 0, body.length);
+
+                //淇濈暀鍓╀綑鐨勬暟鎹紝浠ユ鐢�
+                bytes.clear();
+                for (int i = index + lenght; i < recevieBytes.length; i++) {
+                    bytes.add(recevieBytes[i]);
+                }
+                LinkResponse response = new LinkResponse();
+                response.setSource_ipAddress(ipaddress);
+                response.setTopic(topic);
+                if (HDLLinkConfig.getInstance().ifNeedEncrypt(response.getTopic())) {
+                    //闇�瑕佽В瀵�
+                    byte[] bodyBytes = AesUtil.aesDecrypt(body, HDLLinkConfig.getInstance().getLocalSecret());
+                    if (bodyBytes != null) {
+                        body = bodyBytes;
+                    } else {
+                        try {
+                            //涔嬪墠鐨勭増鏈繖鍧楁槸鏄庢枃鐨�
+                            if (!topic.contains("heartbeat_reply")) {
+                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
+                                    LogUtils.e("瑙e瘑澶辫触锛屾暟鎹唴瀹规槸锛歕r\n" + Base64.getEncoder().encodeToString(body));
+                                else {
+                                    LogUtils.e("瑙e瘑澶辫触锛屾暟鎹唴瀹规槸锛歕r\n" + new String(body, "utf-8"));
+                                }
+                            }
+                        } catch (Exception e) {
+                        }
+                    }
+                }
+
+                String bodyString = new String(body, "utf-8");
+                response.setData(bodyString);
+                LogUtils.i( "鎺ユ敹鍒版暟鎹�:" + response.getTopic() + "\r\n" + response.getData());
+                //闈炴甯告暟鎹紝杩斿洖
+                if (!((bodyString.startsWith("{") &&bodyString.endsWith("}"))
+                        || (bodyString.startsWith("[")&&bodyString.endsWith("]")))) {
+                    continue;
+                }
+                //瑙f瀽瀹屾垚,topic鍙戦�佷竴娆�
+                EventDispatcher.getInstance().post(response.getTopic(), response);
+            }
+            return null;
+
+//            //瑙f瀽娴�
+//            byte[] data = (byte[]) msg;
+//            bytes.addAll(ByteUtils.toByteList(data));
+//
+//            byte[] byteArray = ByteUtils.toByteArray(bytes);
+//            int headIndex = ByteUtils.getByteIndexOf(byteArray, head);
+//            if (headIndex > 0) {
+//                //绉诲姩鍒癶ead 寮�濮嬩綅缃�
+//                bytes.subList(0, headIndex).clear();
+//                byteArray = ByteUtils.toByteArray(bytes);
+//            }
+//
+//            int bodyIndex = ByteUtils.getByteIndexOf(byteArray, body);
+//            if (bodyIndex < 0) {
+//                //澶撮儴鏈幏鍙栧畬鎴�
+//                return null;
+//            }
+//            int bodyStartIndex = bodyIndex + body.length;
+//
+//            //瑙f瀽澶撮儴
+//            ProtocolParse parse = new ProtocolParse(byteArray);
+//            response.setTopic(parse.getTopic());
+//
+//            int bodyLength = parse.getLength();
+//            if (bodyLength > 0) {
+//                if (byteArray.length >= bodyLength + bodyStartIndex) {
+//                    byte[] body = ByteUtils.getRangeBytes(bytes, bodyStartIndex, bodyStartIndex + bodyLength);
+//
+//                    if (HDLLinkConfig.getInstance().ifNeedEncrypt(response.getTopic())) {
+//                        //闇�瑕佽В瀵�
+//                        byte[] bodyBytes = AesUtil.aesDecrypt(body, HDLLinkConfig.getInstance().getLocalSecret());
+////                        byte[] bodyBytes = AESUtils.decryptAES(body,AuthenticateConfig.getInstance().getLocalSecret());
+//                        if (bodyBytes != null) {
+//                            response.setData(new String(bodyBytes, "utf-8"));
+////                            LogUtils.i("TAG", "瑙e瘑 涓婚锛�"+response.getTopic()+ " body: "+response.getData());
+//                        } else {
+//                            //瑙e瘑澶辫触锛岃繑鍥炲師鏁版嵁
+//                            response.setData(new String(body, "utf-8"));
+//                        }
+//
+//                    } else {
+//                        response.setData(new String(body, "utf-8"));
+//                    }
+//
+//                    if (byteArray.length >= bodyLength + bodyStartIndex) {
+//                        //淇濆瓨浣欑暀
+//                        byte[] remaining = ByteUtils.getRangeBytes(bytes, bodyStartIndex + bodyLength, byteArray.length);
+//                        bytes.clear();
+//                        for (byte b : remaining) {
+//                            bytes.add(b);
+//                        }
+//                    }
+//                    //瑙f瀽瀹屾垚,topic鍙戦�佷竴娆�
+//                    EventDispatcher.getInstance().post(response.getTopic(), response);
+//                    return response;
+//                }
+//            } else if (bodyLength == 0) {
+//                //body涓虹┖
+//                return response;
+//            }
 
         }
         return null;

--
Gitblit v1.8.0