package org.yzh.protocol.basics; import io.github.yezhihao.netmc.core.model.Message; import io.github.yezhihao.netmc.session.Session; import io.github.yezhihao.protostar.annotation.Field; import io.github.yezhihao.protostar.util.ToStringBuilder; import io.netty.buffer.ByteBuf; import org.yzh.protocol.commons.MessageId; import java.beans.Transient; /** * @author yezhihao * https://gitee.com/yezhihao/jt808-server */ public class JTMessage implements Message { @Field(length = 2, desc = "消息ID") protected int messageId; @Field(length = 2, desc = "消息体属性") protected int properties; @Field(length = 1, desc = "协议版本号", version = 1) protected int protocolVersion; @Field(length = 6, charset = "BCD", desc = "终端手机号", version = {-1, 0}) @Field(length = 10, charset = "BCD", desc = "终端手机号", version = 1) protected String clientId; @Field(length = 2, desc = "流水号") protected int serialNo; @Field(length = 2, desc = "消息包总数") protected Integer packageTotal; @Field(length = 2, desc = "包序号") protected Integer packageNo; /** bcc校验 */ protected boolean verified = true; protected transient Session session; protected transient ByteBuf payload; public JTMessage() { } public JTMessage(int messageId) { this.messageId = messageId; } public JTMessage copyBy(JTMessage that) { this.setClientId(that.getClientId()); this.setProtocolVersion(that.getProtocolVersion()); this.setVersion(that.isVersion()); return this; } public JTMessage messageId(int messageId) { this.messageId = messageId; return this; } public int getMessageId() { return messageId; } public void setMessageId(int messageId) { this.messageId = messageId; } public int getProperties() { return properties; } public void setProperties(int properties) { this.properties = properties; } public int getProtocolVersion() { return protocolVersion; } public void setProtocolVersion(int protocolVersion) { this.protocolVersion = protocolVersion; } public String getClientId() { return clientId; } public void setClientId(String clientId) { this.clientId = clientId; } public int getSerialNo() { return serialNo; } public void setSerialNo(int serialNo) { this.serialNo = serialNo; } public Integer getPackageTotal() { if (isSubpackage()) return packageTotal; return null; } public void setPackageTotal(Integer packageTotal) { this.packageTotal = packageTotal; } public Integer getPackageNo() { if (isSubpackage()) return packageNo; return null; } public void setPackageNo(Integer packageNo) { this.packageNo = packageNo; } public boolean isVerified() { return verified; } public void setVerified(boolean verified) { this.verified = verified; } @Transient public Session getSession() { return session; } public void setSession(Session session) { this.session = session; } @Transient public ByteBuf getPayload() { return payload; } public void setPayload(ByteBuf payload) { this.payload = payload; } public int reflectMessageId() { if (messageId != 0) return messageId; return reflectMessageId(this.getClass()); } public static int reflectMessageId(Class clazz) { io.github.yezhihao.protostar.annotation.Message messageType = clazz.getAnnotation(io.github.yezhihao.protostar.annotation.Message.class); if (messageType != null && messageType.value().length > 0) return messageType.value()[0]; return 0; } public boolean transform() { return true; } public boolean noBuffer() { return true; } private static final int BODY_LENGTH = 0b0000_0011_1111_1111; private static final int ENCRYPTION = 0b00011_100_0000_0000; private static final int SUBPACKAGE = 0b0010_0000_0000_0000; private static final int VERSION = 0b0100_0000_0000_0000; private static final int RESERVED = 0b1000_0000_0000_0000; /** 消息体长度 */ public int getBodyLength() { return this.properties & BODY_LENGTH; } public void setBodyLength(int bodyLength) { this.properties ^= (properties & BODY_LENGTH); this.properties |= bodyLength; } /** 加密方式 */ public int getEncryption() { return (properties & ENCRYPTION) >> 10; } public void setEncryption(int encryption) { this.properties ^= (properties & ENCRYPTION); this.properties |= (encryption << 10); } /** 是否分包 */ public boolean isSubpackage() { return (properties & SUBPACKAGE) == SUBPACKAGE; } public void setSubpackage(boolean subpackage) { if (subpackage) this.properties |= SUBPACKAGE; else this.properties ^= (properties & SUBPACKAGE); } /** 是否有版本 */ public boolean isVersion() { return (properties & VERSION) == VERSION; } public void setVersion(boolean version) { if (version) this.properties |= VERSION; else this.properties ^= (properties & VERSION); } /** 保留位 */ public boolean isReserved() { return (properties & RESERVED) == RESERVED; } public void setReserved(boolean reserved) { if (reserved) this.properties |= RESERVED; else this.properties ^= (properties & RESERVED); } protected StringBuilder toStringHead() { final StringBuilder sb = new StringBuilder(768); sb.append(MessageId.getName(messageId)); sb.append('['); sb.append("cid=").append(clientId); sb.append(",msgId=").append(messageId); sb.append(",version=").append(protocolVersion); sb.append(",serialNo=").append(serialNo); sb.append(",props=").append(properties); sb.append(",verified=").append(verified); if (isSubpackage()) { sb.append(",pt=").append(packageTotal); sb.append(",pn=").append(packageNo); } sb.append(']'); sb.append(','); return sb; } @Override public String toString() { String result = ToStringBuilder.toString(toStringHead(), this, false, "messageId", "clientId", "protocolVersion", "serialNo", "properties", "packageTotal", "packageNo"); return result; } }