| 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; | 
|     } | 
| } |