All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.nichetoolkit.socket.codec.SocketJt808MessageCoder Maven / Gradle / Ivy

package io.github.nichetoolkit.socket.codec;

import io.github.nichetoolkit.socket.util.ByteHexUtils;
import io.github.nichetoolkit.socket.util.Jt808Utils;
import lombok.extern.slf4j.Slf4j;

/**
 * 

SocketJt808MessageCoder

* @author Cyan ([email protected]) * @version v1.0.0 */ @Slf4j public class SocketJt808MessageCoder implements MessageCoder { private static final byte MSG_BROKER = 0x7E; /** * 含标识位 */ private static final int MSG_MIN_LEN = 15; private static final int MSG_MIN_LEN_2019 = 20; /** * 含标识位 */ private static final int MSG_MIN_LEN_WITH_PKG = 19; private static final int MSG_MIN_LEN_WITH_PKG_2019 = 24; private static final int MAX_READ_LEN = 1024 * 10; @Override public boolean decode(BufferCache bufferCache) { /** 有数据时,读取前 8 字节判断消息长度 */ if (bufferCache.remaining() > 0) { /** 标记初始位置 */ bufferCache.mark(); /** 读取一字节 检查是否标识位 */ byte byteBuf = bufferCache.read(); if (byteBuf == MSG_BROKER) { /** 设置一个长度缓存 */ int pos = 1; /** 是标识位 循环读取 直到 下一个标识位 为止 */ for (int i = 0; i < bufferCache.remaining(); ) { byteBuf = bufferCache.read(); pos++; if (byteBuf == MSG_BROKER) { /** 读取到 下一个标识位 并且重置缓存 */ break; } } /** 循环终结 但是 还是没找到最后的标识位 继续读取 重新解析 */ if (byteBuf != MSG_BROKER) { /** FIXME 如果只有一个 标识位 会导致一直读取的问题 需要设置一个限定长度 读取超过这个长度 就直接丢弃 */ /** 目前设置成 10K 以后会加入配置 */ if (pos < MAX_READ_LEN) { bufferCache.reset(); } return false; } /** 小于最小包长度 截断 重新读取 剩余的 字节 */ if (pos < MSG_MIN_LEN) { log.warn("data is too short ... drop !"); return bufferCache.remaining() > 0; } /** 重置缓存 */ bufferCache.reset(); /** 读取缓存 */ byte[] packageBuf = new byte[pos]; bufferCache.read(packageBuf); log.trace("origin data : {}", ByteHexUtils.parseHex(packageBuf)); /** 转义 转义后的值 已经去掉了 标识位 */ packageBuf = Jt808Utils.retrans(packageBuf); log.trace("trans data : {}", ByteHexUtils.parseHex(packageBuf)); /** 校验失败 丢掉当前包 继续读取剩余的字节 */ boolean verify = Jt808Utils.verify(packageBuf); if (!verify) { log.warn("verify failed {}", bufferCache.address()); return bufferCache.remaining() > 0; } /** 校验成功 检查 长度 并输出到下一步操作 */ byte[] body = ByteHexUtils.subbyte(packageBuf, 2, 4); int sizeBuf = Jt808Utils.messageBodyLength(body); boolean version2019 = Jt808Utils.isVersion2019(body); boolean isSlice = Jt808Utils.isSlicePackage(body); int size; if (isSlice) { if (version2019) { size = sizeBuf + MSG_MIN_LEN_WITH_PKG_2019 - 2; } else { size = sizeBuf + MSG_MIN_LEN_WITH_PKG - 2; } } else { if (version2019) { size = sizeBuf + MSG_MIN_LEN_2019 - 2; } else { size = sizeBuf + MSG_MIN_LEN - 2; } } /** 检查长度 */ if (size == packageBuf.length) { /** 长度符合 输出 */ log.trace("handle data : {}", ByteHexUtils.parseHex(packageBuf)); /** 带有校验位的完整消息 */ bufferCache.write(packageBuf); return bufferCache.remaining() > 0; } /** 长度不符合 */ log.warn("wrong data length expected {}, real {} drop !", size, packageBuf.length); return bufferCache.remaining() > 0; } else { log.warn("wrong data structure {}", bufferCache.address()); for (int i = 0; i < bufferCache.remaining(); ) { if (bufferCache.read() == MSG_BROKER) { /** 如果发送数据不正确 找到下一个0x7e 截断后 再读取一遍 */ return true; } } } } /** 处理成功,让父类进行接收下个包 */ return false; } @Override public byte[] encode(byte[] bytes) { return Jt808Utils.trans(Jt808Utils.addVerify(bytes)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy