From 134209ad70f82051da3ce63471df0cc8f778e57d Mon Sep 17 00:00:00 2001
From: panlili2024 <14743743+panlili2024@user.noreply.gitee.com>
Date: 星期三, 05 三月 2025 14:30:19 +0800
Subject: [PATCH] 增加source屏扫码绑定住宅接口

---
 HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/protocol/LinkMessageDecoder.java |  378 ++++++++++++++++++++++++++++++-----------------------
 1 files changed, 214 insertions(+), 164 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 15bc3bc..38438d9 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
@@ -3,36 +3,19 @@
 
 import android.os.Build;
 import android.text.TextUtils;
-import android.util.Log;
 
 import androidx.annotation.RequiresApi;
 
-import com.google.gson.reflect.TypeToken;
-import com.hdl.sdk.common.config.TopicConstant;
 import com.hdl.sdk.common.event.EventDispatcher;
-import com.hdl.sdk.common.exception.HDLLinkException;
-import com.hdl.sdk.common.utils.ByteUtils;
 import com.hdl.sdk.common.utils.LogUtils;
-import com.hdl.sdk.common.utils.SPUtils;
-import com.hdl.sdk.common.utils.gson.GsonConvert;
-import com.hdl.sdk.connect.HDLLink;
 import com.hdl.sdk.connect.bean.LinkResponse;
-import com.hdl.sdk.connect.bean.request.AuthenticateRequest;
-import com.hdl.sdk.connect.bean.response.DeviceDeleteResponse;
-import com.hdl.sdk.connect.bean.response.DeviceInfoResponse;
-import com.hdl.sdk.connect.callback.HDLLinkCallBack;
 import com.hdl.sdk.connect.config.HDLLinkConfig;
-import com.hdl.sdk.connect.socket.HDLAuthSocket;
-import com.hdl.sdk.connect.socket.HDLSocket;
 import com.hdl.sdk.connect.utils.AesUtil;
+import com.hdl.sdk.connect.utils.ByteBufferUtils;
 import com.hdl.sdk.socket.codec.ByteToMessageDecoder;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import android.util.Base64;
-
-import kotlin.ParameterName;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
 
 /**
  * Created by Tong on 2021/9/22.
@@ -40,13 +23,31 @@
  */
 public class LinkMessageDecoder extends ByteToMessageDecoder<LinkResponse> {
 
-    private final List<Byte> bytes;
+    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();
-//    private final byte[] body = "\r\n\r\n".getBytes();
 
     public LinkMessageDecoder() {
-        this.bytes = new ArrayList<>();
+        byteBuffer = ByteBuffer.allocate(1024 * 200);//100K
     }
 
     /// <summary>
@@ -55,11 +56,16 @@
     /// <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:", ""));
+        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;
@@ -84,15 +90,14 @@
     /**
      * 鑾峰彇鏁版嵁鐨勫紑濮嬩綅缃�
      *
-     * @param arrayList 鎺ユ敹鍒扮殑鎵�鏈夋暟鎹�
      * @return 鏁版嵁浣嶇殑寮�濮嬬储寮�
      */
-    int getDataIndex(List<Byte> arrayList) {
+    int getBodyIndex() {
         byte r = (byte) '\r';
         byte n = (byte) '\n';
-        for (int i = 0; i < arrayList.size(); i++) {
+        for (int i = 0; i < byteBuffer.position(); i++) {
             //鎵惧嚭鏁版嵁鍐呭鍓嶉潰鐨勪袱涓崲琛�
-            if (3 <= i && arrayList.get(i - 3) == r && arrayList.get(i - 2) == n && arrayList.get(i - 1) == r && arrayList.get(i) == n) {
+            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;
             }
@@ -100,14 +105,73 @@
         return -1;
     }
 
-    void initReceiveData(List<Byte> list) {
+    /**
+     * 鑾峰彇澶撮儴鏁版嵁
+     *
+     * @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 < list.size() - head.length; index++) {
+        for (; index < byteBuffer.position() - head.length; index++) {
             isMatch = true;
             for (int j = 0, k = 0; j < head.length; j++, k++) {
-                if (head[j] != list.get(index + k)) {
+                if (head[j] != byteBuffer.get(index + k)) {
                     isMatch = false;
                     break;
                 }
@@ -118,164 +182,150 @@
         }
 
         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));
+            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));
+        }
+    }
+
+
+    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();
     }
 
 
     @RequiresApi(api = Build.VERSION_CODES.O)
     @Override
     protected synchronized LinkResponse decoder(Object msg, String ipaddress) throws Exception {
-        if (msg instanceof byte[]) {
-            bytes.addAll(ByteUtils.toByteList((byte[]) msg));
+        if (msg == null || !(msg instanceof byte[])) {
+            return null;
+        }
+
+        byte[] bytes = (byte[]) msg;
+        try {
+            byteBuffer.put(bytes);
+        } catch (Exception e) {
+            LogUtils.e("鎺ユ敹鍒版暟鎹紓甯�:\r\n" + e.getMessage());
+            byteBuffer.flip();
+            byteBuffer.clear();
+        }
+
+        try {
             //濡傛灉澶氭潯鍛戒护鎵撳寘鍦ㄤ竴鏉℃暟鎹腑锛岄兘闇�瑕佸鐞嗗畬
             while (true) {
-                initReceiveData(bytes);
-                byte[] recevieBytes = ByteUtils.toByteArray(bytes);
-                String data = new String(recevieBytes);
+                removeInVoidBytes();//绉婚櫎鍙兘瀛樺湪鐨勬棤鏁堟暟鎹�
 
-                String[] topMsgs = data.split("\r\n");
+                //澶撮儴鏁版嵁
+                String header = getHeader();
+
+                if (header == null) {
+                    break;
+                }
+                String[] topMsgs = header.split("\r\n");
 
                 String topic = getTopic(topMsgs);
-                if (topic == null) {
-                    break;
-                }
-
                 int lenght = getLenght(topMsgs);
-
-                if (lenght <= 0) {
-                    //澶撮儴鏁版嵁杩樻病鏈夋帴鏀跺畬鎴�
+                if (topic == null || lenght <= 0) {
+                    //鑾峰彇涓嶅埌涓婚鎴栬�呭ご閮ㄦ暟鎹繕娌℃湁鎺ユ敹瀹屾垚
                     break;
                 }
+
+                int bodyIndex = getBodyIndex();
                 //鏄惁宸茬粡鑾峰彇瀹屾暣鎵�鏈夌殑鏁版嵁
-                byte[] body = new byte[lenght];
-                int index = getDataIndex(bytes);
-                if (bytes.size() < index + lenght) {
+                byte[] body = getBody(bodyIndex, lenght);
+
+                if (body == null) {
                     //褰撳墠鏁版嵁杩樻病鏈夋帴鏀跺畬鎴�
                     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);
-                Log.d("panlili", "----->source_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.encodeToString(body, Base64.NO_WRAP));
-                                else {
-                                    LogUtils.e("瑙e瘑澶辫触锛屾暟鎹唴瀹规槸锛歕r\n" + new String(body, "utf-8"));
-                                }
-                            }
-                        } catch (Exception e) {
-                        }
-                    }
-                }
+                remove(bodyIndex + lenght);
 
-                String bodyString = new String(body, "utf-8");
-                response.setData(bodyString);
-                LogUtils.i("鎺ユ敹鍒版暟鎹�:" + response.getTopic() + "\r\n" + response.getData());
-
-                String updateLocalSecret = String.format(TopicConstant.LINK_BROADCAST, HDLLinkConfig.getInstance().getGatewayId());
-                String deleteNetwork = "";
-                if (HDLLinkConfig.getInstance().getDeviceInfoBean() != null) {
-                    deleteNetwork = String.format(TopicConstant.DELETE_NOTIFY, HDLLinkConfig.getInstance().getDeviceInfoBean().getOID());
-                }
-
-                if (response.getTopic().equals("/user/all/custom/gateway/search")) {
-                    HDLAuthSocket.getInstance().UploadGatewayInfo(new HDLLinkCallBack() {
-                        @Override
-                        public void onSuccess(String msg) {
-//                            LogUtils.i("UploadGatewayInfo onSucceed");
-                        }
-
-                        @Override
-                        public void onError(HDLLinkException e) {
-//                            LogUtils.i("UploadGatewayInfo onError");
-                        }
-                    });
-                } else if (response.getTopic().equals(updateLocalSecret) || response.getTopic().equals(TopicConstant.LINK_BROADCAST)) {
-                    try {
-                        DeviceInfoResponse deviceInfoResponse = GsonConvert.getGson().fromJson(response.getData(), new TypeToken<DeviceInfoResponse>() {
-                        }.getType());
-
-                        if (deviceInfoResponse != null && deviceInfoResponse.getObjects() != null) {
-                            if (!TextUtils.isEmpty(deviceInfoResponse.getObjects().getLocalSecret())) {
-                                byte[] baseBytes = Base64.decode(deviceInfoResponse.getObjects().getLocalSecret(), Base64.NO_WRAP);
-                                String mackey = "";
-                                if (!TextUtils.isEmpty(SPUtils.getString("auth_mackey_key", ""))) {
-                                    mackey = SPUtils.getString("auth_mackey_key", "");
-                                    byte[] bodyBytes = AesUtil.aesDecrypt(baseBytes, mackey.substring(mackey.length() - 16));
-                                    String localSecret = new String(bodyBytes, "utf-8");
-                                    Log.d("panlili", "鏇存柊瀵嗛挜----->localSecret= " + localSecret);
-                                    HDLLinkConfig.getInstance().setLocalSecret(localSecret);
-                                }
-                            }
-                        }
-                    } catch (Exception e) {
-                        LogUtils.i("LinkMessageDecoder.java:getLocalSecret----->e= " + e.getMessage());
-                    }
-                } else if (response.getTopic().equals(deleteNetwork)) {
-                    try {
-                        DeviceDeleteResponse deviceDeleteResponse = GsonConvert.getGson().fromJson(response.getData(), new TypeToken<DeviceDeleteResponse>() {
-                        }.getType());
-                        if (deviceDeleteResponse != null && deviceDeleteResponse.getObjects() != null) {
-                            HDLSocket.getInstance().deleteNetwork(deviceDeleteResponse.getObjects().get(0).getOID(), new HDLLinkCallBack() {
-                                @Override
-                                public void onSuccess(String msg) {
-                                    LogUtils.i("deleteNetwork onSucceed");
-                                    if (HDLLink.getInstance().listener != null) {
-                                        HDLLink.getInstance().listener.onSuccess(msg);
-                                    }
-                                }
-
-                                @Override
-                                public void onError(HDLLinkException e) {
-                                    LogUtils.i("deleteNetwork onError");
-                                    if (HDLLink.getInstance().listener != null) {
-                                        HDLLink.getInstance().listener.onFailure();
-                                    }
-                                }
-                            });
-                        }
-                    } catch (Exception e) {
-                        LogUtils.i("LinkMessageDecoder.java:deleteNetwork----->e= " + e.getMessage());
-                    }
-                }
-
-                //闈炴甯告暟鎹紝杩斿洖
-                if (!((bodyString.startsWith("{") && bodyString.endsWith("}"))
-                        || (bodyString.startsWith("[") && bodyString.endsWith("]")))) {
+                if (topic.contains("heartbeat_reply")) {
+//                    if (packet.getSocket() != null) {
+//                        packet.getSocket().setSoTimeout(10 * 1000);
+//                    }
                     continue;
                 }
+
+                LinkResponse response = new LinkResponse();
+                response.setSource_ipAddress(ipaddress);
+                response.setTopic(topic);
+
+                if (encrypt(body)) {
+                    //闇�瑕佽В瀵�
+                    if (!TextUtils.isEmpty(HDLLinkConfig.getInstance().getLocalSecret())) {
+                        byte[] bodyBytes = AesUtil.aesDecrypt(body, HDLLinkConfig.getInstance().getLocalSecret());
+                        if (bodyBytes != null) {
+                            response.setData(new String(bodyBytes, StandardCharsets.UTF_8));
+                        } else {
+                            LogUtils.e("瑙e瘑澶辫触\r\n" + topic);
+                            response.setData(new String(body, "utf-8"));
+                            continue;
+                        }
+                    }
+                } else {
+                    response.setData(new String(body, "utf-8"));
+                }
+
+                LogUtils.i("鏈湴鎺ユ敹鍒版暟鎹�:\r\n" + response.getTopic() + "\r\n" + response.getData() + "\r\n" + response.getData().length());
+
                 //瑙f瀽瀹屾垚,topic鍙戦�佷竴娆�
                 EventDispatcher.getInstance().post(response.getTopic(), response);
             }
-            return null;
-
+        } catch (Exception ee) {
+            LogUtils.e("澶勭悊鎺ユ敹鐨勬暟鎹紓甯�:\r\n" + ee.getMessage());
         }
         return null;
     }
+
+    //鏄惁鍔犲瘑
+    private boolean encrypt(byte[] bytes) {
+        if (bytes[0] == '{' && bytes[bytes.length - 1] == '}' || (bytes[0] == '[' && bytes[bytes.length - 1] == ']')) {
+            return false;
+        }
+        return true;
+    }
 }
+
+

--
Gitblit v1.8.0