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