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 | 355 +++++++++++++++++++++++++++++++++++----------------------- 1 files changed, 214 insertions(+), 141 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 f5ba2c0..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 @@ -1,24 +1,21 @@ package com.hdl.sdk.connect.protocol; -import android.annotation.TargetApi; import android.os.Build; -import android.util.Log; +import android.text.TextUtils; +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; -import com.hdl.sdk.common.utils.ByteUtils; +import com.hdl.sdk.common.utils.LogUtils; import com.hdl.sdk.connect.bean.LinkResponse; +import com.hdl.sdk.connect.config.HDLLinkConfig; import com.hdl.sdk.connect.utils.AesUtil; -import com.hdl.sdk.connect.utils.ProtocolParse; +import com.hdl.sdk.connect.utils.ByteBufferUtils; import com.hdl.sdk.socket.codec.ByteToMessageDecoder; -import java.util.ArrayList; -import java.util.Base64; -import java.util.List; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; /** * Created by Tong on 2021/9/22. @@ -26,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> @@ -41,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; @@ -70,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; } @@ -86,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; } @@ -104,155 +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)); + protected synchronized LinkResponse decoder(Object msg, String ipaddress) throws Exception { + 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]); + remove(bodyIndex + lenght); + + 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 (HDLLinkConfig.getInstance().ifNeedEncrypt(response.getTopic())) { + + if (encrypt(body)) { //闇�瑕佽В瀵� - 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) { + 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")); } - 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; - } + 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; - -// //瑙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; -// } - + } 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