From ee16db5e1cbc1c27bdbc1984567b5e61a3d005dd Mon Sep 17 00:00:00 2001
From: lizhanwei <Dana_Lee1016@126.com>
Date: 星期一, 17 二月 2020 23:36:27 +0800
Subject: [PATCH] 提交协议库

---
 im_lib/src/main/java/com/safeluck/aykj/decoder/BinMessageCoder.java                    |   30 
 im_lib/src/main/java/com/safeluck/aykj/decoder/BCDCoder.java                           |   18 
 im_lib/src/main/java/com/safeluck/aykj/annotation/Length.java                          |   34 +
 im_lib/src/main/java/com/safeluck/aykj/decoder/BaseDecoder.java                        |   23 
 im_lib/src/main/java/com/safeluck/aykj/message/ParseException.java                     |   15 
 im_lib/src/main/java/com/safeluck/aykj/decoder/DefaultHexCoder.java                    |   18 
 app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/JWD.java           |   19 
 im_lib/src/main/java/com/safeluck/aykj/decoder/BcdDateTimeCoder.java                   |   26 
 im_lib/src/main/java/com/anyun/im_lib/netty/NettyTcpClient.java                        |   18 
 im_lib/src/main/java/com/safeluck/aykj/annotation/BcdDateTime.java                     |   16 
 im_lib/src/main/java/com/safeluck/aykj/decoder/Int16LECoder.java                       |   42 +
 im_lib/src/main/java/com/safeluck/aykj/decoder/GBKStringDecoder.java                   |   63 +
 app/src/main/java/safeluck/drive/evaluation/platformMessage/utils/MessageManager.java  |   63 +
 im_lib/src/main/java/com/safeluck/aykj/annotation/BcdDate.java                         |   16 
 im_lib/src/main/java/com/safeluck/aykj/decoder/Int16Coder.java                         |   29 
 im_lib/src/main/java/com/safeluck/aykj/decoder/UTF8StringDecoder.java                  |   37 +
 im_lib/src/main/java/com/safeluck/aykj/decoder/Int32LECoder.java                       |   39 +
 im_lib/src/main/java/com/safeluck/aykj/decoder/BcdDateCoder.java                       |   28 
 im_lib/src/main/java/com/safeluck/aykj/annotation/Int16LE.java                         |   18 
 im_lib/src/main/java/com/safeluck/aykj/decoder/BitStateCoder.java                      |   45 +
 im_lib/src/main/java/com/safeluck/aykj/annotation/Int32LE.java                         |   17 
 app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/Param0104.java     |   14 
 app/src/main/java/safeluck/drive/evaluation/platformMessage/JKRegisterMessage.java     |   31 
 app/src/main/java/safeluck/drive/evaluation/fragment/TcpFragment.java                  |   62 +
 app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/JWDCoder.java      |   29 
 im_lib/src/main/java/com/safeluck/aykj/decoder/BytesCoder.java                         |   19 
 app/src/main/java/safeluck/drive/evaluation/platformMessage/ServerCommonRsp.java       |    8 
 im_lib/src/main/java/com/safeluck/aykj/annotation/Int16.java                           |   20 
 im_lib/src/main/java/com/safeluck/aykj/annotation/Int32.java                           |   20 
 im_lib/src/main/java/com/safeluck/aykj/annotation/Message.java                         |   15 
 im_lib/src/main/java/com/safeluck/aykj/annotation/BitState.java                        |   15 
 app/src/main/java/safeluck/drive/evaluation/im/MessageProcessor.java                   |   10 
 im_lib/src/main/java/com/safeluck/aykj/annotation/UTF8.java                            |   14 
 app/src/main/java/safeluck/drive/evaluation/platformMessage/JKClientCommonMessage.java |   26 
 app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/PhoneCoder.java    |   29 
 app/src/main/java/safeluck/drive/evaluation/platformMessage/utils/MessageEscaper.java  |   85 ++
 im_lib/src/main/java/com/safeluck/aykj/decoder/Int32Coder.java                         |   33 
 app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/Phone.java         |   19 
 im_lib/src/main/java/com/safeluck/aykj/annotation/GBK.java                             |   15 
 im_lib/src/main/java/com/safeluck/aykj/utils/BitState.java                             |   56 +
 im_lib/src/main/java/com/safeluck/aykj/decoder/ByteCoder.java                          |   24 
 im_lib/src/main/java/com/safeluck/aykj/annotation/AnnotationRegister.java              |   58 +
 im_lib/src/main/java/com/safeluck/aykj/annotation/Bytes.java                           |   14 
 im_lib/src/main/java/com/safeluck/aykj/annotation/Order.java                           |   15 
 im_lib/src/main/java/com/safeluck/aykj/annotation/Ascii.java                           |   14 
 app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/Param8103.java     |   14 
 app/src/main/java/safeluck/drive/evaluation/platformMessage/JK2019MessageBase.java     |  167 ++++
 im_lib/src/main/java/com/safeluck/aykj/utils/ArrayUtils.java                           |   15 
 im_lib/src/main/java/com/safeluck/aykj/annotation/Int8.java                            |   16 
 im_lib/src/main/java/com/safeluck/aykj/annotation/Hex.java                             |   14 
 im_lib/src/main/java/com/safeluck/aykj/decoder/IMessageCoder.java                      |   13 
 im_lib/src/main/java/com/safeluck/aykj/message/BinMessageBase.java                     |  397 +++++++++++
 im_lib/src/main/java/com/safeluck/aykj/annotation/FromEnd.java                         |   17 
 im_lib/src/main/java/com/safeluck/aykj/utils/BytesUtils.java                           |  110 +++
 54 files changed, 2,006 insertions(+), 16 deletions(-)

diff --git a/app/src/main/java/safeluck/drive/evaluation/fragment/TcpFragment.java b/app/src/main/java/safeluck/drive/evaluation/fragment/TcpFragment.java
index 9eecc59..03fb5f8 100644
--- a/app/src/main/java/safeluck/drive/evaluation/fragment/TcpFragment.java
+++ b/app/src/main/java/safeluck/drive/evaluation/fragment/TcpFragment.java
@@ -16,12 +16,18 @@
 import androidx.lifecycle.Observer;
 
 import com.anyun.exam.lib.util.Speaker;
+import com.anyun.im_lib.util.ByteUtil;
 import com.google.android.material.textfield.TextInputEditText;
+import com.safeluck.aykj.utils.BytesUtils;
 
 import me.yokeyword.fragmentation.SupportFragment;
 import safeluck.drive.evaluation.DB.criterias.CriteriaForI;
 import safeluck.drive.evaluation.DB.criterias.viewmodel.CriteriaIViewModel;
 import safeluck.drive.evaluation.R;
+import safeluck.drive.evaluation.im.MessageProcessor;
+import safeluck.drive.evaluation.platformMessage.GainStuMessage;
+import safeluck.drive.evaluation.platformMessage.JKClientCommonMessage;
+import safeluck.drive.evaluation.platformMessage.JKRegisterMessage;
 import safeluck.drive.evaluation.platformMessage.RegisterMessage;
 import safeluck.drive.evaluation.im.IMSClientBootstrap;
 
@@ -103,8 +109,9 @@
 
                 String userId = "100002";
                 String token = "token_" + userId;
-                String hosts = "[{\"host\":\"47.93.80.84\", \"port\":12125}]";
-//                String hosts = "[{\"host\":\"192.168.31.77\", \"port\":12125}]";
+//                String hosts = "[{\"host\":\"47.93.80.84\", \"port\":12125}]";
+//                String hosts = "[{\"host\":\"47.93.157.103\", \"port\":2020}]";
+                String hosts = "[{\"host\":\"192.168.31.77\", \"port\":12125}]";
 
                 IMSClientBootstrap.getInstance().init(userId,token,hosts,1);
                 break;
@@ -122,12 +129,51 @@
                 //娓呴櫎app_status 琛�
 //                OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(AppStatusInitWork.class).build();
 //                WorkManager.getInstance(_mActivity).enqueue(oneTimeWorkRequest);
-                RegisterMessage registerMessage = new RegisterMessage((short)0x802);
-                registerMessage.setCityid((short) 1);
-                registerMessage.setProviceId((short)23);
-                registerMessage.setImei("460123874561");
-                registerMessage.setModel("123");
-                registerMessage.setSn("2019101500000001");
+//                RegisterMessage registerMessage = new RegisterMessage((short)0x802);
+//                registerMessage.setCityid((short) 1);
+//                registerMessage.setProviceId((short)23);
+//                registerMessage.setImei("460123874561");
+//                registerMessage.setModel("123");
+//                registerMessage.setSn("2019101500000001");
+
+
+//                GainStuMessage gainStuMessage = new GainStuMessage((short) 0x201);
+//                gainStuMessage.setId("123456789");
+//                gainStuMessage.setExamaCourse((short) 0);
+//                MessageProcessor.getInstance().sendMessage(gainStuMessage.toBytes());
+
+                ByteUtil.str2Bcd("13021245");
+                String strbcd=ByteUtil.bcd2Str(ByteUtil.str2Bcd("13021245"));
+                Log.i(TAG, "onClick: strbcd="+strbcd);
+
+                JKRegisterMessage jkRegisterMessage = new JKRegisterMessage();
+                jkRegisterMessage.setMessageLen(55);
+//                jkRegisterMessage.phone = "13021245";
+                jkRegisterMessage.phone = "0008618513021245";
+                jkRegisterMessage.proviceid = 23;
+                jkRegisterMessage.messageId = 0x100;
+                jkRegisterMessage.protocalVer = 235;
+                jkRegisterMessage.cityid = 1;
+                jkRegisterMessage.imei = "460123874561";
+                jkRegisterMessage.model = "123";
+                jkRegisterMessage.sn = "0314200100000004";
+
+                Log.i(TAG, "onClick: msg len "+jkRegisterMessage.getMessageLen()+" "+       jkRegisterMessage.props.value);
+                byte[] str = jkRegisterMessage.toBytes();
+                MessageProcessor.getInstance().sendMessage(str);
+                Log.i(TAG, "onClick: "+ BytesUtils.bytesToHexString(str)+" ============");
+
+                JKClientCommonMessage jkClientCommonMessage =new JKClientCommonMessage();
+                jkClientCommonMessage.setMessageLen(5);
+                jkClientCommonMessage.messageId = 0x8100;
+                jkClientCommonMessage.protocalVer = 235;
+//                jkClientCommonMessage.phone = "13021245";
+                jkClientCommonMessage.respMessageId = "8001";
+                jkClientCommonMessage.respNo = 15;
+                jkClientCommonMessage.result =1;
+                String str1 = jkClientCommonMessage.toString();
+
+                Log.i(TAG, "onClick1: "+ str1+" ============");
                 break;
         }
     }
diff --git a/app/src/main/java/safeluck/drive/evaluation/im/MessageProcessor.java b/app/src/main/java/safeluck/drive/evaluation/im/MessageProcessor.java
index a38cf10..73a3a7f 100644
--- a/app/src/main/java/safeluck/drive/evaluation/im/MessageProcessor.java
+++ b/app/src/main/java/safeluck/drive/evaluation/im/MessageProcessor.java
@@ -2,9 +2,12 @@
 
 import android.util.Log;
 
+import com.anyun.exam.lib.MyLog;
 import com.anyun.im_lib.util.ByteUtil;
 
+import safeluck.drive.evaluation.platformMessage.PlatFormConstant;
 import safeluck.drive.evaluation.platformMessage.RegisterResp;
+import safeluck.drive.evaluation.platformMessage.ServerCommonRsp;
 import safeluck.drive.evaluation.util.CThreadPoolExecutor;
 import safeluck.drive.evaluation.util.Utils;
 
@@ -49,6 +52,13 @@
             case (short) 0x8100:
                 RegisterResp registerResp = new RegisterResp(datas);
                 break;
+            case (short) 0x8001://鏈嶅姟鍣ㄧ 閫氱敤搴旂瓟
+                ServerCommonRsp serverCommonRsp = new ServerCommonRsp(datas);
+                if (serverCommonRsp.getResult() == PlatFormConstant.SUCCESS){
+                    MyLog.i(PlatFormConstant.TAG,"纭"+serverCommonRsp.getMsgId()+"娑堟伅鎴愬姛");
+                }
+                break;
+
         }
     }
 
diff --git a/app/src/main/java/safeluck/drive/evaluation/platformMessage/JK2019MessageBase.java b/app/src/main/java/safeluck/drive/evaluation/platformMessage/JK2019MessageBase.java
new file mode 100644
index 0000000..e10896b
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/platformMessage/JK2019MessageBase.java
@@ -0,0 +1,167 @@
+package safeluck.drive.evaluation.platformMessage;
+
+
+import android.util.Log;
+
+import com.safeluck.aykj.annotation.AnnotationRegister;
+import com.safeluck.aykj.annotation.Int16;
+import com.safeluck.aykj.annotation.Int8;
+import com.safeluck.aykj.annotation.Length;
+import com.safeluck.aykj.annotation.Order;
+import com.safeluck.aykj.decoder.BitStateCoder;
+import com.safeluck.aykj.decoder.Int16Coder;
+import com.safeluck.aykj.message.BinMessageBase;
+import com.safeluck.aykj.utils.BitState;
+import com.safeluck.aykj.utils.BytesUtils;
+
+import safeluck.drive.evaluation.platformMessage.decoder.JWD;
+import safeluck.drive.evaluation.platformMessage.decoder.JWDCoder;
+import safeluck.drive.evaluation.platformMessage.decoder.Phone;
+import safeluck.drive.evaluation.platformMessage.decoder.PhoneCoder;
+
+public class JK2019MessageBase extends BinMessageBase {
+    static {
+        AnnotationRegister.register(JWD.class, new JWDCoder());
+        AnnotationRegister.register(Phone.class, new PhoneCoder());
+
+    }
+    static Int16Coder coder = new Int16Coder();
+    public JK2019MessageBase()
+    {
+        this.messageNo = getMessageNo();
+        String message_name = this.getClass().getSimpleName();
+        if(message_name.startsWith("JTMessage"))
+        {
+            String message_id = message_name.substring(9,13);
+            if(message_id.equals("Unkn") ){
+                return;
+            }
+            this.messageId= coder.decode(message_id);
+        }
+        this.setMultiPacket(false);
+        this.registerDisableField("totalPacket");
+        this.registerDisableField("packetNo");
+    }
+
+
+    @Override
+    public void parse(String hex){
+
+        BitStateCoder coder = new BitStateCoder();
+        this.props = coder.decode(hex.substring(8,12));
+        if(this.isMultiPacket())
+        {
+            this.removeDisableField("totalPacket");
+            this.removeDisableField("packetNo");
+        }
+        super.parse(hex);
+    }
+
+    @Override
+    public String toString()
+    {
+        if(!this.isMultiPacket())
+        {
+            this.registerDisableField("totalPacket");
+            this.registerDisableField("packetNo");
+        }
+        //璁$畻娑堟伅浣撻暱搴�
+        String hex = super.toString();
+        Log.i(PlatFormConstant.TAG, "toString: 娑堟伅浣撻暱搴︼細"+hex);
+        int message_head_len = 19;
+        if(this.isMultiPacket())
+        {
+            message_head_len+=4;
+        }
+//        int len1 = this.getMessageLen();
+        int len2 = hex.length()/2-message_head_len;
+        this.setMessageLen(len2);
+        //璁$畻鏍¢獙
+        hex = super.toString();
+        byte[] bytes = BytesUtils.hexStringToBytes(hex);
+        bytes[bytes.length - 2] = BytesUtils.xor(bytes,1,bytes.length -2);
+
+
+        return BytesUtils.bytesToHexString(bytes);
+    }
+    @Order(1)
+    @Int8
+    public int head=0x7E;
+    @Order(2)
+    @Int8
+    public int protocalVer=0x80;
+    @Order(3)
+    @Int16
+    public int messageId;
+    @Order(4)
+    @Length(2)
+    @com.safeluck.aykj.annotation.BitState
+    public BitState props = new BitState((byte) 0);
+    @Order(5)
+    @Phone
+    public String phone;
+    @Order(6)
+    @Int16
+    public int messageNo;
+    @Order(7)
+    @Int8
+    public int reserved = 0;
+    @Order(8)
+    @Int16
+    public int totalPacket;
+    @Order(9)
+    @Int16
+    public int packetNo;
+
+
+    @Order(Integer.MAX_VALUE-10001)
+    @Int8
+    public int checksum;
+    @Order(Integer.MAX_VALUE-10000)
+    @Int8
+    public int end=0x7E;
+
+    /**
+     * 鏄惁娑堟伅缁忚繃鍒嗗寘澶勭悊
+     * @param b
+     */
+    public void setMultiPacket(boolean b)
+    {
+        this.props.set(13,b);
+    }
+    public boolean isMultiPacket()
+    {
+        return this.props.get(13);
+    }
+
+    /**
+     * 鑾峰彇灞炴�т腑鐨勬秷鎭綋闀垮害
+     * @return
+     */
+    public int getMessageLen()
+    {
+        BitState state = new BitState((short)this.props.value);
+        for (int i = 0; i < 10; i++)
+        {
+            state.set(10 + i, false);
+        }
+        return (int) state.value;
+    }
+
+    /**
+     * 璁剧疆灞炴�т腑鐨勬秷鎭綋闀垮害
+     * @param len
+     */
+    public void setMessageLen(int len)
+    {
+        BitState state = new BitState((short)len);
+
+        for (int i = 0; i < 10; i++)
+        {
+            this.props.set(i, state.get(i));
+        }
+    }
+
+
+
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/platformMessage/JKClientCommonMessage.java b/app/src/main/java/safeluck/drive/evaluation/platformMessage/JKClientCommonMessage.java
new file mode 100644
index 0000000..007b2fc
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/platformMessage/JKClientCommonMessage.java
@@ -0,0 +1,26 @@
+package safeluck.drive.evaluation.platformMessage;
+
+import com.safeluck.aykj.annotation.Hex;
+import com.safeluck.aykj.annotation.Int16;
+import com.safeluck.aykj.annotation.Int8;
+import com.safeluck.aykj.annotation.Length;
+import com.safeluck.aykj.annotation.Order;
+
+public class JKClientCommonMessage extends JK2019MessageBase {
+
+    public static int SUCCESS=0;
+    public static int FAIL=1;
+    public static int ERROR_MSG=2;
+    public static int NOT_SUPPORT=3;
+
+    @Order(1)
+    @Int16
+    public int respNo;
+    @Order(2)
+    @Length(2)
+    @Hex
+    public String respMessageId;
+    @Order(3)
+    @Int8
+    public int result;
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/platformMessage/JKRegisterMessage.java b/app/src/main/java/safeluck/drive/evaluation/platformMessage/JKRegisterMessage.java
new file mode 100644
index 0000000..28684cb
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/platformMessage/JKRegisterMessage.java
@@ -0,0 +1,31 @@
+package safeluck.drive.evaluation.platformMessage;
+
+
+import com.safeluck.aykj.annotation.Ascii;
+import com.safeluck.aykj.annotation.Int16;
+import com.safeluck.aykj.annotation.Length;
+import com.safeluck.aykj.annotation.Order;
+
+public class JKRegisterMessage extends JK2019MessageBase {
+
+    @Order(1)
+    @Int16
+    public int proviceid;
+    @Order(2)
+    @Int16
+    public int cityid;
+
+    @Order(3)
+    @Length(20)
+    @Ascii
+    public String model;
+    @Order(4)
+    @Length(16)
+    @Ascii
+    public String sn;
+    @Order(5)
+    @Length(15)
+    @Ascii
+    public String imei;
+
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/platformMessage/ServerCommonRsp.java b/app/src/main/java/safeluck/drive/evaluation/platformMessage/ServerCommonRsp.java
index f902c37..eb311ec 100644
--- a/app/src/main/java/safeluck/drive/evaluation/platformMessage/ServerCommonRsp.java
+++ b/app/src/main/java/safeluck/drive/evaluation/platformMessage/ServerCommonRsp.java
@@ -49,4 +49,12 @@
     public short getResult() {
         return result;
     }
+
+    public short getMsgId() {
+        return msgId;
+    }
+
+    public short getMsg_serial_num() {
+        return msg_serial_num;
+    }
 }
diff --git a/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/JWD.java b/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/JWD.java
new file mode 100644
index 0000000..892fdb5
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/JWD.java
@@ -0,0 +1,19 @@
+package safeluck.drive.evaluation.platformMessage.decoder;
+
+import com.safeluck.aykj.annotation.Length;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zw on 2017/6/15.
+ */
+
+@Length(4)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface JWD {
+//    Class<? extends IMessageCoder<?>>[] coder() default Int32Coder.class;
+}
\ No newline at end of file
diff --git a/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/JWDCoder.java b/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/JWDCoder.java
new file mode 100644
index 0000000..b326b3f
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/JWDCoder.java
@@ -0,0 +1,29 @@
+package safeluck.drive.evaluation.platformMessage.decoder;
+
+import com.safeluck.aykj.decoder.BaseDecoder;
+import com.safeluck.aykj.decoder.Int32Coder;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * Created by zw on 2017/6/15.
+ */
+
+public class JWDCoder  extends BaseDecoder<Double> {
+    Int32Coder coder = new Int32Coder();
+    @Override
+    public Double decode(String str) {
+        double ret = coder.decode(str);
+        double x = ret / 1000000;
+        BigDecimal bg = new BigDecimal(x);
+        double f1 = bg.setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue();
+        return f1;
+    }
+
+    @Override
+    public String encode(Double str) {
+        int jwd = (int)(str * 1000000);
+        return coder.encode(jwd);
+    }
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/Param0104.java b/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/Param0104.java
new file mode 100644
index 0000000..7b08e78
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/Param0104.java
@@ -0,0 +1,14 @@
+package safeluck.drive.evaluation.platformMessage.decoder;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by shiyu on 2016/12/28.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD,ElementType.TYPE})
+public @interface Param0104 {
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/Param8103.java b/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/Param8103.java
new file mode 100644
index 0000000..d65ee7b
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/Param8103.java
@@ -0,0 +1,14 @@
+package safeluck.drive.evaluation.platformMessage.decoder;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by shiyu on 2016/12/28.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD,ElementType.TYPE})
+public @interface Param8103 {
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/Phone.java b/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/Phone.java
new file mode 100644
index 0000000..64ea167
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/Phone.java
@@ -0,0 +1,19 @@
+package safeluck.drive.evaluation.platformMessage.decoder;
+
+import com.safeluck.aykj.annotation.Length;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zw on 2017/6/15.
+ */
+
+@Length(8)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface Phone {
+//    Class<? extends IMessageCoder<?>>[] coder() default Int32Coder.class;
+}
\ No newline at end of file
diff --git a/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/PhoneCoder.java b/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/PhoneCoder.java
new file mode 100644
index 0000000..184a749
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/platformMessage/decoder/PhoneCoder.java
@@ -0,0 +1,29 @@
+package safeluck.drive.evaluation.platformMessage.decoder;
+
+
+import android.util.Log;
+
+import com.anyun.im_lib.util.ByteUtil;
+import com.safeluck.aykj.decoder.BaseDecoder;
+import com.safeluck.aykj.utils.BytesUtils;
+
+public class PhoneCoder  extends BaseDecoder<String> {
+    private static final String TAG = "PhoneCoder";
+    @Override
+    public String decode(String str) {
+        return str.substring(8);
+    }
+
+    @Override
+    public String encode(String str) {
+        Log.i(TAG, "encode: "+str);
+        if(str==null||"".equalsIgnoreCase(str))
+        {
+//            str ="00000000000";
+            str ="0000000000000000";
+        }
+     byte[] bcdBytes = ByteUtil.str2Bcd(str);
+//        return "00000"+str;
+        return BytesUtils.bytesToHexString(bcdBytes);
+    }
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/platformMessage/utils/MessageEscaper.java b/app/src/main/java/safeluck/drive/evaluation/platformMessage/utils/MessageEscaper.java
new file mode 100644
index 0000000..1ef040e
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/platformMessage/utils/MessageEscaper.java
@@ -0,0 +1,85 @@
+package safeluck.drive.evaluation.platformMessage.utils;
+
+
+import com.safeluck.aykj.utils.ArrayUtils;
+
+/**
+ * Created by zw on 2017/7/8.
+ * 钃濈墮鍗忚杞箟
+ */
+
+public class MessageEscaper {
+
+    public  byte[] escape(byte[] source_bytes)
+    {
+        byte[] return_bytes = new byte[source_bytes.length*2];
+
+        int size = source_bytes.length;
+        int pos = 0;
+        for (int i = 0; i < size; i++)
+        {
+            if (i == 0||i==size-1)
+            {
+                return_bytes[pos++] = source_bytes[i];
+                continue;
+            }
+            if (source_bytes[i] == 0x7d)
+            {
+                return_bytes[pos++] = 0x7d;
+                return_bytes[pos++] = 0x01;
+            }
+            else if (source_bytes[i] == 0x7e)
+            {
+                return_bytes[pos++] = 0x7d;
+                return_bytes[pos++] = 0x02;
+            }
+            else
+            {
+                return_bytes[pos++] = source_bytes[i];
+            }
+        }
+
+        return ArrayUtils.subArray(return_bytes,0,pos);
+
+
+    }
+
+    public  byte[] unescape(byte[] cmd_bytes)
+    {
+        //杞箟杩樺師
+        int len = cmd_bytes.length;
+        byte[] return_bytes = new byte[cmd_bytes.length];
+
+        //int len = ByteHelper.HexString2Byte(cmd, cmd_bytes);
+        int pos = 0;
+        for (int i = 0; i < len; i++)
+        {
+            if (i == len - 1)
+            {
+                return_bytes[pos++] = cmd_bytes[i];
+                continue;
+            }
+
+            if (cmd_bytes[i] == 0x7d && cmd_bytes[i + 1] == 0x02)
+            {
+                return_bytes[pos++] = 0x7e;
+                i++;
+                continue;
+            }
+            else if (cmd_bytes[i] == 0x7d && cmd_bytes[i + 1] == 0x01)
+            {
+                return_bytes[pos++] = 0x7d;
+                i++;
+                continue;
+            }
+            else
+            {
+                return_bytes[pos++] = cmd_bytes[i];
+            }
+        }
+        return ArrayUtils.subArray(return_bytes,0,pos);
+
+
+    }
+
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/platformMessage/utils/MessageManager.java b/app/src/main/java/safeluck/drive/evaluation/platformMessage/utils/MessageManager.java
new file mode 100644
index 0000000..8f4a78d
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/platformMessage/utils/MessageManager.java
@@ -0,0 +1,63 @@
+//package safeluck.drive.evaluation.platformMessage.utils;
+//
+//import com.safeluck.aykj.decoder.BitStateCoder;
+//import com.safeluck.aykj.decoder.Int16Coder;
+//import com.safeluck.aykj.utils.BitState;
+//
+//import safeluck.drive.evaluation.platformMessage.JK2019MessageBase;
+//
+///**
+// * Created by zhouwei on 2016/12/7.
+// */
+//
+//public final class MessageManager {
+//
+//    public static JK2019MessageBase get(String cmd) {
+//        String head = cmd.substring(4,8);
+//        String classname = "aykj.message.jt808_2016.server.JTMessage"+head;
+//        if("0900".equals(head)||"8900".equals(head))
+//            classname = "aykj.message.jt808_2016.JTMessage"+head;
+//        Class c = null;
+//        try {
+//            c = Class.forName(classname);
+//        } catch (ClassNotFoundException e) {
+//            classname = "aykj.message.jt808_2016.device.JTMessage"+head;
+//            try {
+//                c = Class.forName(classname);
+//            } catch (ClassNotFoundException e1) {
+////                c = JTMessageUnknown.class;
+//            }
+//        }
+//        try {
+//
+//            JK2019MessageBase ret = (JK2019MessageBase)c.newInstance();
+//            ret.parse(cmd);
+//            if(ret.messageId==0x8900||ret.messageId==0x0900){
+////                JTMessageExtend ext = (JTMessageExtend)ret;
+//                if(ret.messageId==0x8900)
+////                    classname = "aykj.message.jt808_2016.server.ExtendMessage"+ String.format("%04X", ext.extend_id);
+//                else
+////                    classname = "aykj.message.jt808_2016.device.ExtendMessage"+ String.format("%04X", ext.extend_id);
+//                try {
+//                    c = Class.forName(classname);
+//                } catch (ClassNotFoundException e) {
+//                    classname = "aykj.message.jt808_2016.device.JTMessage"+head;
+//                    try {
+//                        c = Class.forName(classname);
+//                    } catch (ClassNotFoundException e1) {
+////                        c = JTMessageUnknown.class;
+//                    }
+//                }
+//
+//                JK2019MessageBase ext_ret = (JK2019MessageBase)c.newInstance();
+//                ext_ret.parse(cmd);
+//                ret = ext_ret;
+//            }
+//            return ret;
+//        } catch (InstantiationException e) {
+//            throw new RuntimeException(e);
+//        } catch (IllegalAccessException e) {
+//            throw new RuntimeException(e);
+//        }
+//    }
+//}
diff --git a/im_lib/src/main/java/com/anyun/im_lib/netty/NettyTcpClient.java b/im_lib/src/main/java/com/anyun/im_lib/netty/NettyTcpClient.java
index 9b233a5..11be1ce 100644
--- a/im_lib/src/main/java/com/anyun/im_lib/netty/NettyTcpClient.java
+++ b/im_lib/src/main/java/com/anyun/im_lib/netty/NettyTcpClient.java
@@ -12,6 +12,7 @@
 import com.anyun.im_lib.listener.IMSConnectStatusCallback;
 import com.anyun.im_lib.listener.OnEventListener;
 import com.anyun.im_lib.util.ByteUtil;
+import com.safeluck.aykj.utils.BytesUtils;
 
 import java.nio.ByteBuffer;
 import java.util.Vector;
@@ -218,14 +219,14 @@
                     imsConnectStatusCallback.onConnected();
                 }
                 // TODO: 2019/12/12  杩炴帴鎴愬姛 锛屽彂閫佹彙鎵嬫秷鎭紙闇�瑕佺殑璇濃�斺�旓級
-                try {
-                    ByteBuf byteBuf = ByteBufAllocator.DEFAULT.ioBuffer();
-                    byteBuf.writeBytes(mOnEventListener.getRegisterMessage());
-                    Log.i(TAG, "鍙戦�佹秷鎭�: "+ ByteUtil.byte2HexStr(mOnEventListener.getRegisterMessage()));
-                    channel.writeAndFlush(byteBuf);
-                } catch (Exception e) {
-                    Log.i(TAG, "鍙戦�佹秷鎭け璐ワ紝reason="+e.getMessage()+"\t");
-                }
+//                try {
+//                    ByteBuf byteBuf = ByteBufAllocator.DEFAULT.ioBuffer();
+//                    byteBuf.writeBytes(mOnEventListener.getRegisterMessage());
+//                    Log.i(TAG, "鍙戦�佹秷鎭�: "+ ByteUtil.byte2HexStr(mOnEventListener.getRegisterMessage()));
+//                    channel.writeAndFlush(byteBuf);
+//                } catch (Exception e) {
+//                    Log.i(TAG, "鍙戦�佹秷鎭け璐ワ紝reason="+e.getMessage()+"\t");
+//                }
                 break;
             case IMSConfig.CONNECT_STATE_FAILURE:
                 default:
@@ -331,6 +332,7 @@
             Log.i(TAG, "sendMsg fail,channel涓虹┖"+msg);
         }
         try {
+            Log.i(TAG, "sendMsg: "+ BytesUtils.bytesToHexString(msg));
             ByteBuf byteBuf = ByteBufAllocator.DEFAULT.ioBuffer();
             byteBuf.writeBytes(msg);
             channel.writeAndFlush(byteBuf);
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/AnnotationRegister.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/AnnotationRegister.java
new file mode 100644
index 0000000..5180fa0
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/AnnotationRegister.java
@@ -0,0 +1,58 @@
+package com.safeluck.aykj.annotation;
+
+import com.safeluck.aykj.decoder.*;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+public final class AnnotationRegister {
+
+    static HashMap hashMap = new HashMap();
+
+    static
+    {
+        register(Int16.class,new Int16Coder());
+        register(Int32.class,new Int32Coder());
+        register(Int8.class,new ByteCoder());
+        register(GBK.class,new GBKStringDecoder());
+        register(Ascii.class,new GBKStringDecoder());
+
+        register(BitState.class,new BitStateCoder());
+        register(Hex.class,new DefaultHexCoder());
+        register(UTF8.class,new UTF8StringDecoder());
+        register(Bytes.class,new BytesCoder());
+        register(Message.class,new BinMessageCoder());
+        register(BcdDate.class,new BcdDateCoder());
+        register(BcdDateTime.class,new BcdDateTimeCoder());
+        register(Int16LE.class,new Int16LECoder());
+        register(Int32LE.class,new Int32LECoder());
+
+
+    }
+
+    public static void register(Class annotation, IMessageCoder<?> coder)
+    {
+        hashMap.put(annotation,coder);
+    }
+    public static IMessageCoder getCoder(Class annotation)
+    {
+        IMessageCoder decoder =  (IMessageCoder)hashMap.get(annotation);
+        if(decoder instanceof BaseDecoder)
+        {
+            BaseDecoder baseDecoder = (BaseDecoder)decoder;
+            if(!baseDecoder.isSingleton)
+            {
+                try {
+                    decoder = decoder.getClass().newInstance();
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+        return decoder;
+    }
+
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/Ascii.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/Ascii.java
new file mode 100644
index 0000000..3edb73a
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/Ascii.java
@@ -0,0 +1,14 @@
+package com.safeluck.aykj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD,ElementType.TYPE})
+public @interface Ascii {
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/BcdDate.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/BcdDate.java
new file mode 100644
index 0000000..dd52925
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/BcdDate.java
@@ -0,0 +1,16 @@
+package com.safeluck.aykj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zw on 2017/6/15.
+ */
+@Length(3)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface BcdDate {
+//    Class<? extends IMessageCoder<?>>[] coder() default Int32Coder.class;
+}
\ No newline at end of file
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/BcdDateTime.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/BcdDateTime.java
new file mode 100644
index 0000000..f4c4874
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/BcdDateTime.java
@@ -0,0 +1,16 @@
+package com.safeluck.aykj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zw on 2017/6/15.
+ */
+@Length(6)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface BcdDateTime {
+//    Class<? extends IMessageCoder<?>>[] coder() default Int32Coder.class;
+}
\ No newline at end of file
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/BitState.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/BitState.java
new file mode 100644
index 0000000..fe1b872
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/BitState.java
@@ -0,0 +1,15 @@
+package com.safeluck.aykj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface BitState {
+//    Class<? extends IMessageCoder<?>>[] coder() default Int32Coder.class;
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/Bytes.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/Bytes.java
new file mode 100644
index 0000000..d6e79e0
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/Bytes.java
@@ -0,0 +1,14 @@
+package com.safeluck.aykj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD,ElementType.TYPE})
+public @interface Bytes {
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/FromEnd.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/FromEnd.java
new file mode 100644
index 0000000..80de160
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/FromEnd.java
@@ -0,0 +1,17 @@
+package com.safeluck.aykj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zw on 2017/7/11.
+ * 浠庣粨灏惧紑濮嬭В鏋愯�屼笉鏄粠寮�澶�
+ */
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface FromEnd {
+    int value();
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/GBK.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/GBK.java
new file mode 100644
index 0000000..7a23503
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/GBK.java
@@ -0,0 +1,15 @@
+package com.safeluck.aykj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD,ElementType.TYPE})
+public @interface GBK {
+
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/Hex.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/Hex.java
new file mode 100644
index 0000000..1e90e5d
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/Hex.java
@@ -0,0 +1,14 @@
+package com.safeluck.aykj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD,ElementType.TYPE})
+public @interface Hex {
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/Int16.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/Int16.java
new file mode 100644
index 0000000..33f3bf9
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/Int16.java
@@ -0,0 +1,20 @@
+package com.safeluck.aykj.annotation;
+
+import com.safeluck.aykj.decoder.IMessageCoder;
+import com.safeluck.aykj.decoder.Int16Coder;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+
+@Length(2)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD,ElementType.TYPE})
+public @interface Int16 {
+//    Class<? extends IMessageCoder<?>>[] coder() default Int16Coder.class;
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/Int16LE.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/Int16LE.java
new file mode 100644
index 0000000..9de1c03
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/Int16LE.java
@@ -0,0 +1,18 @@
+package com.safeluck.aykj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ * 灏忕妯″紡 浣庝綅鍦ㄥ墠
+ */
+
+@Length(2)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD,ElementType.TYPE})
+public @interface Int16LE {
+//    Class<? extends IMessageCoder<?>>[] coder() default Int16Coder.class;
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/Int32.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/Int32.java
new file mode 100644
index 0000000..22109af
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/Int32.java
@@ -0,0 +1,20 @@
+package com.safeluck.aykj.annotation;
+
+import com.safeluck.aykj.decoder.IMessageCoder;
+import com.safeluck.aykj.decoder.Int16Coder;
+import com.safeluck.aykj.decoder.Int32Coder;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+@Length(4)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface Int32 {
+//    Class<? extends IMessageCoder<?>>[] coder() default Int32Coder.class;
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/Int32LE.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/Int32LE.java
new file mode 100644
index 0000000..467a386
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/Int32LE.java
@@ -0,0 +1,17 @@
+package com.safeluck.aykj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ * 灏忕妯″紡 浣庝綅鍦ㄥ墠
+ */
+@Length(4)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface Int32LE {
+//    Class<? extends IMessageCoder<?>>[] coder() default Int32Coder.class;
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/Int8.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/Int8.java
new file mode 100644
index 0000000..b31da17
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/Int8.java
@@ -0,0 +1,16 @@
+package com.safeluck.aykj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+@Length(1)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD,ElementType.TYPE})
+public @interface Int8 {
+//    Class<? extends IMessageCoder<?>>[] coder() default Int16Coder.class;
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/Length.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/Length.java
new file mode 100644
index 0000000..08c2070
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/Length.java
@@ -0,0 +1,34 @@
+package com.safeluck.aykj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD,ElementType.TYPE})
+public @interface Length {
+    int value() default 0;
+    String lengthField() default "";
+
+    /**
+     * 濡傛灉闀垮害涓嶈冻鐨勫~鍏呮柟鍚�
+     * @return
+     */
+    PaddingWay paddingWay() default PaddingWay.RIGHT;
+
+    /**
+     * 闀垮害涓嶈冻鐨勫~鍏呭瓧绗�
+     * @return
+     */
+    byte paddingByte() default 0x00;
+    enum PaddingWay {
+        LEFT,RIGHT;
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/Message.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/Message.java
new file mode 100644
index 0000000..ce4af10
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/Message.java
@@ -0,0 +1,15 @@
+package com.safeluck.aykj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD,ElementType.TYPE})
+public @interface Message {
+
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/Order.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/Order.java
new file mode 100644
index 0000000..d1031fb
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/Order.java
@@ -0,0 +1,15 @@
+package com.safeluck.aykj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface Order {
+    int value() default -1;
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/annotation/UTF8.java b/im_lib/src/main/java/com/safeluck/aykj/annotation/UTF8.java
new file mode 100644
index 0000000..a1bc563
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/annotation/UTF8.java
@@ -0,0 +1,14 @@
+package com.safeluck.aykj.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD,ElementType.TYPE})
+public @interface UTF8 {
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/BCDCoder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/BCDCoder.java
new file mode 100644
index 0000000..ac843fe
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/BCDCoder.java
@@ -0,0 +1,18 @@
+package com.safeluck.aykj.decoder;
+
+import com.safeluck.aykj.utils.BytesUtils;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+//public class BCDCoder implements IMessageCoder<String> {
+//    @Override
+//    public String decode(String str) {
+//        return Integer.valueOf(str, 16).intValue();
+//    }
+//
+//    @Override
+//    public String encode(String i) {
+//        return BytesUtils.toHexString(i.byteValue());
+//    }
+//}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/BaseDecoder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/BaseDecoder.java
new file mode 100644
index 0000000..421e899
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/BaseDecoder.java
@@ -0,0 +1,23 @@
+package com.safeluck.aykj.decoder;
+
+
+/**
+ * Created by zhouwei on 2016/12/20.
+ */
+
+public abstract class BaseDecoder<T> implements IMessageCoder<T>  {
+    public boolean isSingleton = true;
+
+    protected Class<? extends T> fieldClass;
+
+
+    @Override
+    public Class<? extends T> getFieldClass() {
+        return fieldClass;
+    }
+
+    @Override
+    public void setFieldClass(Class<? extends T> value) {
+        fieldClass =value;
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/BcdDateCoder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/BcdDateCoder.java
new file mode 100644
index 0000000..41a672a
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/BcdDateCoder.java
@@ -0,0 +1,28 @@
+package com.safeluck.aykj.decoder;
+
+import com.safeluck.aykj.utils.BitState;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Created by zw on 2017/6/15.
+ */
+
+public class BcdDateCoder extends BaseDecoder<Date>  {
+    SimpleDateFormat f= new SimpleDateFormat("yyMMdd");
+    @Override
+    public Date decode(String date) {
+        try {
+            return f.parse(date);
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public String encode(Date date) {
+        return f.format(date);
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/BcdDateTimeCoder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/BcdDateTimeCoder.java
new file mode 100644
index 0000000..fed57fc
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/BcdDateTimeCoder.java
@@ -0,0 +1,26 @@
+package com.safeluck.aykj.decoder;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Created by zw on 2017/6/15.
+ */
+
+public class BcdDateTimeCoder extends BaseDecoder<Date>  {
+    SimpleDateFormat f= new SimpleDateFormat("yyMMddHHmmss");
+    @Override
+    public Date decode(String date) {
+        try {
+            return f.parse(date);
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public String encode(Date date) {
+        return f.format(date);
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/BinMessageCoder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/BinMessageCoder.java
new file mode 100644
index 0000000..7061af6
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/BinMessageCoder.java
@@ -0,0 +1,30 @@
+package com.safeluck.aykj.decoder;
+
+import com.safeluck.aykj.message.BinMessageBase;
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+public class BinMessageCoder extends BaseDecoder<BinMessageBase> {
+
+    public BinMessageCoder()
+    {
+        this.isSingleton = false;
+    }
+    @Override
+    public BinMessageBase decode(String str) {
+        try {
+            BinMessageBase messageBase = this.fieldClass.newInstance();
+            messageBase.parse(str);
+            return messageBase;
+        } catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    @Override
+    public String encode(BinMessageBase i) {
+        return i.toString();
+    }
+
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/BitStateCoder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/BitStateCoder.java
new file mode 100644
index 0000000..943a25f
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/BitStateCoder.java
@@ -0,0 +1,45 @@
+package com.safeluck.aykj.decoder;
+
+import com.safeluck.aykj.utils.BitState;
+import com.safeluck.aykj.utils.BytesUtils;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+public class BitStateCoder extends BaseDecoder<BitState> {
+    Int16Coder int16Coder = new Int16Coder();
+    Int32Coder int32Coder = new Int32Coder();
+    @Override
+    public BitState decode(String str) {
+        if(str.length()==2)
+        {
+            return new BitState(Byte.valueOf(str,16));
+        }
+        if(str.length()==4)
+        {
+            return new BitState(Short.valueOf(str,16));
+        }
+        if(str.length()==8)
+        {
+            return new BitState(Integer.valueOf(str,16));
+        }
+        throw new RuntimeException("BitState闀垮害涓嶅锛屾暟鎹�="+str);
+    }
+
+    @Override
+    public String encode(BitState i) {
+        if(i.total==8)
+        {
+            return BytesUtils.toHexString((byte)i.value);
+        }
+        if(i.total==16)
+        {
+            return int16Coder.encode((int)i.value);
+        }
+        if(i.total==32)
+        {
+            return int32Coder.encode((int)i.value);
+        }
+        throw new RuntimeException("BitState闀垮害涓嶅锛屾暟鎹�="+i.total);
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/ByteCoder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/ByteCoder.java
new file mode 100644
index 0000000..92913e8
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/ByteCoder.java
@@ -0,0 +1,24 @@
+package com.safeluck.aykj.decoder;
+
+import com.safeluck.aykj.utils.BytesUtils;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+public class ByteCoder extends BaseDecoder<Integer> {
+    public static ByteCoder instance = new ByteCoder();
+    @Override
+    public Integer decode(String str) {
+        if(str==null||"".equals(str))
+            return 0;
+        return Integer.valueOf(str, 16).intValue();
+    }
+
+    @Override
+    public String encode(Integer i) {
+        if(i==null)
+            i=0;
+        return BytesUtils.toHexString(i.byteValue());
+    }
+
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/BytesCoder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/BytesCoder.java
new file mode 100644
index 0000000..3775bbd
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/BytesCoder.java
@@ -0,0 +1,19 @@
+package com.safeluck.aykj.decoder;
+
+import com.safeluck.aykj.utils.BytesUtils;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+public class BytesCoder extends BaseDecoder<Object> {
+    @Override
+    public Object decode(String str) {
+        return BytesUtils.hexStringToBytes(str);
+    }
+
+    @Override
+    public String encode(Object i) {
+        byte[] bytes = (byte[])i;
+        return BytesUtils.bytesToHexString(bytes);
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/DefaultHexCoder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/DefaultHexCoder.java
new file mode 100644
index 0000000..0708f53
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/DefaultHexCoder.java
@@ -0,0 +1,18 @@
+package com.safeluck.aykj.decoder;
+
+import com.safeluck.aykj.utils.BytesUtils;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+public class DefaultHexCoder extends BaseDecoder<String> {
+    @Override
+    public String decode(String str) {
+        return str;
+    }
+
+    @Override
+    public String encode(String i) {
+        return i;
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/GBKStringDecoder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/GBKStringDecoder.java
new file mode 100644
index 0000000..cfa5f4c
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/GBKStringDecoder.java
@@ -0,0 +1,63 @@
+package com.safeluck.aykj.decoder;
+
+import com.safeluck.aykj.utils.BytesUtils;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Created by zhouwei on 2016/12/3.
+ */
+
+public class GBKStringDecoder extends BaseDecoder<String> {
+
+    public String stripEnd(String str, String stripChars) {
+        int end;
+        if(str != null && (end = str.length()) != 0) {
+            if(stripChars == null) {
+                while(end != 0 && Character.isWhitespace(str.charAt(end - 1))) {
+                    --end;
+                }
+            } else {
+                if(stripChars.length() == 0) {
+                    return str;
+                }
+
+                while(end != 0 && stripChars.indexOf(str.charAt(end - 1)) != -1) {
+                    --end;
+                }
+            }
+
+            return str.substring(0, end);
+        } else {
+            return str;
+        }
+    }
+
+
+    @Override
+    public String decode(String str) {
+
+        if(str==null)
+            return null;
+        byte[] bytes = BytesUtils.hexStringToBytes(str);
+
+        try {
+
+            String ret = new String(bytes,"gbk").trim();
+            return ret;// this.stripEnd(ret,"\0");
+        } catch (UnsupportedEncodingException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public String encode(String str) {
+        try {
+            if(str==null)
+                return null;
+            return BytesUtils.bytesToHexString(str.getBytes("gbk"));
+        } catch (UnsupportedEncodingException e) {
+            return null;
+        }
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/IMessageCoder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/IMessageCoder.java
new file mode 100644
index 0000000..69eab48
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/IMessageCoder.java
@@ -0,0 +1,13 @@
+package com.safeluck.aykj.decoder;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+public interface IMessageCoder<T> {
+    T decode(String str);
+    String encode(T str);
+
+    Class<? extends T> getFieldClass();
+    void setFieldClass(Class<? extends T> value);
+
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/Int16Coder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/Int16Coder.java
new file mode 100644
index 0000000..3675d30
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/Int16Coder.java
@@ -0,0 +1,29 @@
+package com.safeluck.aykj.decoder;
+
+import com.safeluck.aykj.annotation.Int16;
+import com.safeluck.aykj.utils.BytesUtils;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+public class Int16Coder extends BaseDecoder<Integer> {
+
+    public static Int16Coder instance = new Int16Coder();
+
+    @Override
+    public Integer decode(String str) {
+        if(str==null||"".equals(str))
+            return 0;
+        return Integer.valueOf(str, 16);
+    }
+
+    @Override
+    public String encode(Integer i) {
+        if(i==null)
+            i=0;
+        byte[] b = new byte[2];
+        b[1]= (byte)(i&0xff);
+        b[0]= (byte)(i >> 8);
+        return BytesUtils.bytesToHexString(b);
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/Int16LECoder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/Int16LECoder.java
new file mode 100644
index 0000000..5068d92
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/Int16LECoder.java
@@ -0,0 +1,42 @@
+package com.safeluck.aykj.decoder;
+
+import com.safeluck.aykj.utils.BytesUtils;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+public class Int16LECoder extends BaseDecoder<Integer> {
+
+    public static Int16LECoder instance = new Int16LECoder();
+
+    @Override
+    public Integer decode(String str) {
+
+        byte[] src = BytesUtils.hexStringToBytes(str);
+        int offset = 0;
+        int value;
+        value =  (src[offset] & 0xFF)
+                | ((src[offset + 1] & 0xFF) << 8);
+//                | ((src[offset + 2] & 0xFF) << 16)
+//                | ((src[offset + 3] & 0xFF) << 24));
+        return value;
+//        return Integer.valueOf(Short.reverseBytes(Int16Coder.instance.decode(str).shortValue())&0xFF);
+//        if(str==null||"".equals(str))
+//            return 0;
+//
+//        return Integer.valueOf(str, 16);
+    }
+
+    @Override
+    public String encode(Integer i) {
+        if(i==null)
+            i=0;
+        int value = i.intValue();
+        byte[] src = new byte[2];
+//        src[3] = (byte) ((value >> 24) & 0xFF);
+//        src[2] = (byte) ((value >> 16) & 0xFF);
+        src[1] = (byte) ((value >> 8) & 0xFF);
+        src[0] = (byte) (value & 0xFF);
+        return BytesUtils.bytesToHexString(src);
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/Int32Coder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/Int32Coder.java
new file mode 100644
index 0000000..739f532
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/Int32Coder.java
@@ -0,0 +1,33 @@
+package com.safeluck.aykj.decoder;
+
+import com.safeluck.aykj.annotation.Int32;
+import com.safeluck.aykj.utils.BytesUtils;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+public class Int32Coder extends BaseDecoder<Integer> {
+
+    public static Int32Coder instance = new Int32Coder();
+
+    @Override
+    public Integer decode(String str) {
+        if(str==null||"".equals(str))
+            return 0;
+        return Integer.valueOf(str, 16);
+    }
+
+    @Override
+    public String encode(Integer i) {
+        if(i==null)
+            i=0;
+        //楂樹綅鍦ㄥ墠 32浣嶆暣鏁�
+        int num = i.intValue();
+        byte[] b = new byte[4];
+        b[3]= (byte)(num&0xff);
+        b[2]= (byte)(num >> 8);
+        b[1]= (byte)(num >> 16);
+        b[0]= (byte)(num >> 24);
+        return BytesUtils.bytesToHexString(b);
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/Int32LECoder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/Int32LECoder.java
new file mode 100644
index 0000000..e1ce1b2
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/Int32LECoder.java
@@ -0,0 +1,39 @@
+package com.safeluck.aykj.decoder;
+
+import com.safeluck.aykj.utils.BytesUtils;
+
+/**
+ * Created by zhouwei on 2016/12/1.
+ */
+public class Int32LECoder extends BaseDecoder<Integer> {
+
+    public static Int32LECoder instance = new Int32LECoder();
+
+    @Override
+    public Integer decode(String str) {
+        return Integer.reverseBytes(Int32Coder.instance.decode(str));
+//        byte[] src = BytesUtils.hexStringToBytes(str);
+//        int offset = 0;
+//        int value;
+//        value = (int) ((src[offset] & 0xFF)
+//                | ((src[offset + 1] & 0xFF) << 8)
+//                | ((src[offset + 2] & 0xFF) << 16)
+//                | ((src[offset + 3] & 0xFF) << 24));
+//        return value;
+    }
+    //浣庝綅鍦ㄥ墠 32浣嶆暣鏁�
+    @Override
+    public String encode(Integer i) {
+        return Int32Coder.instance.encode(Integer.reverseBytes(i));
+
+//        if(i==null)
+//            i=0;
+//        int value = i.intValue();
+//        byte[] src = new byte[4];
+//        src[3] = (byte) ((value >> 24) & 0xFF);
+//        src[2] = (byte) ((value >> 16) & 0xFF);
+//        src[1] = (byte) ((value >> 8) & 0xFF);
+//        src[0] = (byte) (value & 0xFF);
+//        return BytesUtils.bytesToHexString(src);
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/decoder/UTF8StringDecoder.java b/im_lib/src/main/java/com/safeluck/aykj/decoder/UTF8StringDecoder.java
new file mode 100644
index 0000000..a6dbdfd
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/decoder/UTF8StringDecoder.java
@@ -0,0 +1,37 @@
+package com.safeluck.aykj.decoder;
+
+import com.safeluck.aykj.utils.BytesUtils;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Created by zhouwei on 2016/12/3.
+ */
+
+public class UTF8StringDecoder extends BaseDecoder<String> {
+
+    @Override
+    public String decode(String str) {
+
+        if(str==null)
+            return null;
+        byte[] bytes = BytesUtils.hexStringToBytes(str);
+
+        try {
+            return new String(bytes,"utf-8");
+        } catch (UnsupportedEncodingException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public String encode(String str) {
+        try {
+            if(str==null)
+                return null;
+            return BytesUtils.bytesToHexString(str.getBytes("utf-8"));
+        } catch (UnsupportedEncodingException e) {
+            return null;
+        }
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/message/BinMessageBase.java b/im_lib/src/main/java/com/safeluck/aykj/message/BinMessageBase.java
new file mode 100644
index 0000000..1ac6965
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/message/BinMessageBase.java
@@ -0,0 +1,397 @@
+package com.safeluck.aykj.message;
+
+import android.util.Log;
+
+import com.safeluck.aykj.annotation.AnnotationRegister;
+import com.safeluck.aykj.annotation.FromEnd;
+import com.safeluck.aykj.annotation.Length;
+import com.safeluck.aykj.annotation.Order;
+import com.safeluck.aykj.decoder.IMessageCoder;
+import com.safeluck.aykj.utils.BytesUtils;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+
+import io.netty.util.internal.PlatformDependent;
+
+@SuppressWarnings("Since15")
+public class BinMessageBase {
+
+    static short m_messageNo;
+    protected  synchronized short getMessageNo()
+    {
+        m_messageNo++;
+        if(m_messageNo>=Short.MAX_VALUE-1)
+        {
+            m_messageNo = 0;
+        }
+        return m_messageNo;
+    }
+
+    static HashMap<Class,FieldDefine[]> fieldDefines = new HashMap<>();
+
+    protected List<String> disabledFields = new ArrayList<>();
+
+    public void parse(String hex)
+    {
+        try {
+            FieldDefine[] fields = this.getFieldDefines();
+
+            int total = hex.length();
+            int used = 0;
+            int dynamic_len_field_count = 0;
+            int relative_len_field_count = 0;
+
+            //濡傛灉鏈変负鍔ㄦ�侀暱搴︾殑锛岃绠楀嚭闀垮害
+            for (FieldDefine fieldDefine : fields) {
+                if (this.disabledFields.contains(fieldDefine.field.getName())) {
+                    continue;
+                }
+                //璁$畻渚濊禆闀垮害瀛楁鏁伴噺
+                if (fieldDefine.relativeLengthField != null) {
+                    relative_len_field_count++;
+                }
+                if (fieldDefine.relativeLengthField == null && fieldDefine.getFieldLen() == 0) {
+                    dynamic_len_field_count++;
+                }
+                //鍔ㄦ�侀暱搴︼紝鍘绘帀鍏朵粬鎵�鏈夊瓧娈电殑闀垮害锛屽墿浣欑殑涓烘瀛楁闀垮害
+                if (fieldDefine.getFieldLen() > 0) {
+                    System.out.println(fieldDefine.field.getName() + "闀垮害=" + fieldDefine.getFieldLen() * 2);
+                    used += (fieldDefine.getFieldLen() * 2);
+                }
+
+            }
+            if (dynamic_len_field_count > 1) {
+                buildException("鍔ㄦ�侀暱搴﹀瓧娈靛彧鑳芥湁涓�涓�");
+            }
+            if (dynamic_len_field_count > 0 && relative_len_field_count > 0) {
+                buildException("鍔ㄦ�侀暱搴﹀瓧娈靛拰渚濊禆闀垮害瀛楁鍙兘鏈変竴涓�");
+            }
+            int dynamic_len = (total - used);
+
+            int start = 0;
+            for (FieldDefine fieldDefine : fields) {
+                if (this.disabledFields.contains(fieldDefine.field.getName())) {
+                    continue;
+                }
+                //瑙f瀽渚濊禆闀垮害
+                if (fieldDefine.relativeLengthField != null) {
+                    try {
+                        Field lengthField = this.getClass().getField(fieldDefine.length.lengthField());
+                        int len = (int) lengthField.get(this);
+                        System.out.println(fieldDefine.field.getName() + ":渚濊禆闀垮害=" + len);
+
+                        fieldDefine.setFieldLen(len);
+                        ;
+                    } catch (Exception e) {
+                        buildException(e.getMessage());
+                    }
+                }
+                int str_hex_len = fieldDefine.getFieldLen() * 2;
+                if (str_hex_len <= 0) {
+                    str_hex_len = dynamic_len;
+                }
+                String field_hex = null;
+                Object value = null;
+                if (fieldDefine.from_end_index >= 0) {
+                    field_hex = hex.substring(hex.length() - str_hex_len - fieldDefine.from_end_index, hex.length() - fieldDefine.from_end_index);
+                    value = fieldDefine.coder.decode(field_hex);
+                } else {
+                    field_hex = hex.substring(start, start + str_hex_len);
+                    start += str_hex_len;
+                    value = fieldDefine.coder.decode(field_hex);
+                }
+                try {
+                    fieldDefine.field.set(this, value);
+//                Object val = fieldDefine.field.get(this);
+//                System.out.println(fieldDefine.field.getName()+":get="+val);
+
+                } catch (IllegalAccessException e) {
+                    this.buildException(e.getMessage());
+                }
+            }
+        }
+        catch (ParseException ex)
+        {
+            throw ex;
+        }
+        catch (Exception ex)
+        {
+            this.buildException(ex.getMessage());
+        }
+    }
+
+    public void registerDisableField(String field)
+    {
+        if(!this.disabledFields.contains(field)) {
+            this.disabledFields.add(field);
+        }
+    }
+    public void removeDisableField(String field)
+    {
+        this.disabledFields.remove(field);
+    }
+
+
+    protected void buildException(String error)
+    {
+        throw new ParseException(error,this);
+    }
+
+    public byte[] toBytes()
+    {
+        String hex = this.toString();
+
+        return BytesUtils.hexStringToBytes(hex);
+
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+        FieldDefine[] fields = this.getFieldDefines();
+        //鍐欏姩鎬侀暱搴﹀瓧娈甸暱搴�
+        for (FieldDefine fieldDefine:fields) {
+
+            if (this.disabledFields.contains(fieldDefine.field.getName())) {
+                continue;
+            }
+            Log.i("PlatFormMessage", "1field: "+fieldDefine.field.getName());
+            if(fieldDefine.relativeLengthField==null)
+                continue;
+            try {
+                Object value = fieldDefine.field.get(this);
+                String hex = fieldDefine.coder.encode(value);
+                if (hex == null) {
+                    fieldDefine.relativeLengthField.set(this, 0);
+                } else {
+                    fieldDefine.relativeLengthField.set(this, hex.length() / 2);
+                }
+            }
+            catch(IllegalAccessException e)
+            {
+                this.buildException(e.getMessage());
+            }
+        }
+
+        for (FieldDefine fieldDefine:fields)
+        {
+            if(this.disabledFields.contains(fieldDefine.field.getName()))
+            {
+                continue;
+            }
+            Log.i("PlatFormMessage", "2field: "+fieldDefine.field.getName());
+            try {
+                Object obj  = fieldDefine.field.get(this);
+                String hex = fieldDefine.coder.encode(obj);
+                if(hex==null)
+                {
+                    hex = "";
+                }
+                if (fieldDefine.field.getName().equalsIgnoreCase("phone")){
+                    Log.i("PlatFormMessage", "phone toString: "+hex
+                    );
+                }
+
+                int defineLen = fieldDefine.getFieldLen();
+                if(hex.length()>defineLen*2&&defineLen>0)
+                {
+                    this.buildException("瀛楁"+fieldDefine.field.getName()+"闀垮害瓒呰繃闄愬埗");
+                }
+                if(hex.length()<defineLen*2&&defineLen>0)
+                {
+                    if(fieldDefine.length.paddingWay()== Length.PaddingWay.RIGHT)
+                    {
+                        hex = this.getPaddingRightString(hex,fieldDefine.getFieldLen()*2, BytesUtils.toHexString(fieldDefine.length.paddingByte()));
+                    }
+                    else
+                    {
+                        hex = this.getPaddingLeftString(hex,fieldDefine.getFieldLen()*2, BytesUtils.toHexString(fieldDefine.length.paddingByte()));
+                    }
+                }
+//                System.out.println(hex);
+                sb.append(hex);
+            } catch (IllegalAccessException e) {
+                this.buildException(e.getMessage());
+            }
+        }
+
+        return sb.toString();
+    }
+    String getPaddingLeftString(String str, int total_len,String padding) {
+        while (str.length() < total_len) {
+            str = padding + str;
+        }
+        return str;
+    }
+    String getPaddingRightString(String str, int total_len,String padding) {
+        while (str.length() < total_len) {
+            str = str+padding;
+        }
+        return str;
+    }
+
+    public synchronized FieldDefine[] getFieldDefines()
+    {
+        if(!fieldDefines.containsKey(this.getClass()))
+        {
+            Field[] fields = this.getClass().getFields();
+            List<FieldDefine> fieldDefineList = new ArrayList<>();
+//            int sort = 0;
+            List<Class> baseClassList = new ArrayList<>();
+            for (Field field:fields)
+            {
+                if(Modifier.isStatic(field.getModifiers()))
+                    continue;
+                if(Modifier.isPrivate(field.getModifiers()))
+                    continue;
+
+                if(field.getAnnotation(Order.class)==null)
+                    continue;
+
+
+                FieldDefine fieldDefine = new FieldDefine(field);
+                if(fieldDefine.coder!=null) {
+
+                    fieldDefineList.add(fieldDefine);
+                    if(baseClassList.indexOf(field.getDeclaringClass())<0)
+                    {
+                        baseClassList.add(field.getDeclaringClass());
+                    }
+                }
+                if(fieldDefine.length.lengthField()!=null&&!"".equals(fieldDefine.length.lengthField()))
+                {
+                    try {
+                        fieldDefine.relativeLengthField = this.getClass().getField(fieldDefine.length.lengthField());
+                    } catch (NoSuchFieldException e) {
+                        this.buildException(e.getMessage());
+                    }
+                }
+
+            }
+            //鎺掑簭鍑哄熀绫�
+            Collections.sort(baseClassList,new Comparator<Class>() {
+                @Override
+                public int compare(Class c1, Class c2) {
+                    if(c2.isAssignableFrom(c1))
+                    {
+                        return 1;
+                    }
+                    return -1;
+                }
+            });
+
+            //閲嶆柊鎺掑簭
+            int sort = 0;
+            for(Class c:baseClassList)
+            {
+                sort+=100;
+                for(FieldDefine fieldDefine:fieldDefineList)
+                {
+                    if(fieldDefine.field.getDeclaringClass().equals(c))//&&fieldDefine.order==0)
+                    {
+                        if(fieldDefine.order+sort>0) {
+                            fieldDefine.order += sort;
+                        }
+                    }
+                }
+            }
+            Collections.sort(fieldDefineList,new Comparator<FieldDefine>() {
+                @Override
+                public int compare(FieldDefine t0, FieldDefine t1) {
+                    int order0 = t0.order;//+(pos0+1);
+                    int order1 = t1.order;//+(pos1+1);
+
+
+                    if(order0>order1)
+                        return 1;
+                    if(order0==order1)
+                        return 0;
+
+                    return -1;
+                }
+            });
+            fieldDefines.put(this.getClass(),fieldDefineList.toArray(new FieldDefine[0]));
+        }
+        FieldDefine[] result = fieldDefines.get(this.getClass());
+        for(FieldDefine fieldDefine:result)
+        {
+            fieldDefine.setFieldLen(0);
+        }
+        return result;
+    }
+
+    class FieldDefine
+    {
+        public FieldDefine(Field field)
+        {
+            Annotation[] annotations = field.getAnnotations();
+            for (Annotation annotation:annotations) {
+                IMessageCoder  decoder =  AnnotationRegister.getCoder(annotation.annotationType());
+                if(decoder!=null) {
+                    decoder.setFieldClass(field.getType());
+                    coder = decoder;
+                    this.length =  annotation.annotationType().getAnnotation(Length.class);
+                    break;
+                }
+            }
+            this.field = field;
+            if(this.length==null) {
+                this.length = field.getAnnotation(Length.class);
+            }
+            if(this.length==null)
+            {
+                buildException(field.getName()+"鏈畾涔夐暱搴�");
+            }
+            Order orderAnnotation = field.getAnnotation(Order.class);
+            if(orderAnnotation!=null)
+            {
+                this.order = orderAnnotation.value();
+            }
+
+            FromEnd fromEnd = field.getAnnotation(FromEnd.class);
+            if(fromEnd!=null)
+            {
+                from_end_index = fromEnd.value();
+            }
+
+        }
+        public Field relativeLengthField;
+        public IMessageCoder coder;
+        public Length length;
+        public Field field;
+        public int order;
+        public int from_end_index = -1;
+        private int field_len;
+        public int getFieldLen()
+        {
+            if(this.length.value()>0)
+                return this.length.value();
+            return field_len;
+        }
+
+        public void setFieldLen(int len)
+        {
+            this.field_len = len;
+        }
+
+        @Override
+        public String toString() {
+            return this.field.toString();
+        }
+
+
+    }
+
+    public String getDescription()
+    {
+        return this.toString();
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/message/ParseException.java b/im_lib/src/main/java/com/safeluck/aykj/message/ParseException.java
new file mode 100644
index 0000000..01460f7
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/message/ParseException.java
@@ -0,0 +1,15 @@
+package com.safeluck.aykj.message;
+
+/**
+ * Created by zhouwei on 2016/12/3.
+ */
+
+public class ParseException extends RuntimeException {
+    public ParseException(String error,BinMessageBase message)
+    {
+        super(error);
+        this.message = message;
+    }
+
+    public BinMessageBase message;
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/utils/ArrayUtils.java b/im_lib/src/main/java/com/safeluck/aykj/utils/ArrayUtils.java
new file mode 100644
index 0000000..2270531
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/utils/ArrayUtils.java
@@ -0,0 +1,15 @@
+package com.safeluck.aykj.utils;
+
+import android.util.Log;
+
+import static com.anyun.im_lib.util.ByteUtil.byte2HexStr;
+
+public class ArrayUtils {
+
+    public static byte[] subArray(byte[] srcBytes, int begin, int length) {
+        byte[] bytes = new byte[length];
+        System.arraycopy(srcBytes,begin,bytes,0,length);
+        Log.i("ArrayUtils", "subArray: "+byte2HexStr(bytes));
+        return bytes;
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/utils/BitState.java b/im_lib/src/main/java/com/safeluck/aykj/utils/BitState.java
new file mode 100644
index 0000000..e442654
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/utils/BitState.java
@@ -0,0 +1,56 @@
+package com.safeluck.aykj.utils;
+
+
+public class BitState {
+    public BitState(int b)
+    {
+        this.value = b;
+        this.total = 32;
+    }
+    public BitState(byte b)
+    {
+        this.value = b;
+        this.total = 8;
+    }
+    public BitState(short b)
+    {
+        this.value = b;
+        this.total = 16;
+    }
+
+    public int total = 32;
+
+    public int value;
+
+    public boolean get(int bit)
+    {
+        int pos = bit;//32 - bit;
+        return (this.value >> pos & 1) == 1;
+    }
+    public void set(int pos, boolean state)
+    {
+        //11000110
+        int move_pos = pos;// 32 - pos;
+        if (state)
+        {
+            this.value = this.value | 1 << move_pos;
+        }
+        else
+        {
+            this.value = this.value & ~(1 << move_pos);
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        String str = Integer.toBinaryString(this.value);
+        return getPaddingRightString(str, this.total,"00");
+    }
+    String getPaddingRightString(String str, int total_len,String padding) {
+        while (str.length() < total_len) {
+            str = str+padding;
+        }
+        return str;
+    }
+}
diff --git a/im_lib/src/main/java/com/safeluck/aykj/utils/BytesUtils.java b/im_lib/src/main/java/com/safeluck/aykj/utils/BytesUtils.java
new file mode 100644
index 0000000..d7204b4
--- /dev/null
+++ b/im_lib/src/main/java/com/safeluck/aykj/utils/BytesUtils.java
@@ -0,0 +1,110 @@
+package com.safeluck.aykj.utils;
+
+public final class BytesUtils {
+	public static String bytesToHexString(byte[] src,int len){  
+		return bytesToHexString(src,0,len);
+	}
+	public static String bytesToHexString(byte[] src){  
+		return bytesToHexString(src,0,src.length);
+	}
+
+	public static String bytesToHexString(byte[] src,int start,int len){  
+	    StringBuilder stringBuilder = new StringBuilder("");  
+	    if (src == null || src.length <= 0) {  
+	        return null;  
+	    }  
+	    for (int i = start; i < len; i++) {  
+	        int v = src[i] & 0xFF;  
+	        String hv = Integer.toHexString(v);  
+	        if (hv.length() < 2) {  
+	            stringBuilder.append(0);  
+	        }  
+	        stringBuilder.append(hv);   
+	    }  
+	    return stringBuilder.toString().toUpperCase();  
+	}  
+	public static byte[] hexStringToBytes(String hexString) {  
+	    if (hexString == null || hexString.equals("")) {  
+	        return null;  
+	    }  
+	    hexString = hexString.toUpperCase();  
+	    int length = hexString.length() / 2;  
+	    char[] hexChars = hexString.toCharArray();  
+	    byte[] d = new byte[length];  
+	    for (int i = 0; i < length; i++) {  
+	        int pos = i * 2;  
+	        d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));  
+	    }  
+	    return d;  
+	}  
+	private static byte charToByte(char c) {  
+	    return (byte) "0123456789ABCDEF".indexOf(c);  
+	}
+
+	public static byte xor(byte[] bytes,int start,int end)
+	{
+		if (bytes.length < end)
+		{
+			throw new RuntimeException("璁$畻xor鐨勬椂鍊檚ize涓嶈冻");
+		}
+		int s1 = bytes[start];
+		for (int i = start + 1; i < end; i++)
+		{
+			s1 = s1 ^ bytes[i];
+		}
+		return (byte)s1;
+	}
+
+
+	public static byte xor(byte[] bytes)
+	{
+		return xor(bytes,0,bytes.length);
+	}
+	public static String toHexString(byte b)
+	{
+		String hex = Integer.toHexString(b&0xff).toUpperCase();
+		if(hex.length()==1)
+		{
+			return "0"+hex;
+		}
+		return hex;
+	}
+	public static int sum(byte[] bytes,int start,int end)
+	{
+		if (bytes.length < end)
+		{
+			throw new RuntimeException("璁$畻sum鐨勬椂鍊檚ize涓嶈冻");
+		}
+		int s1 = 0;
+		for (int i = start; i < end; i++)
+		{
+//			System.out.println(bytes[i]&0xFF);
+			s1 += (bytes[i]&0xFF);
+//			System.out.println("sum="+s1);
+		}
+		return s1;
+
+
+//		int sum = 0;
+//		for(byte b:bytes)
+//		{
+//			sum+=b;
+//		}
+//		return sum;
+	}
+
+	public static int sum(byte[] bytes)
+	{
+		return sum(bytes,0,bytes.length);
+	}
+	
+	public static int getInt32(byte[] bytes,int start){  
+        int result = 0;
+        int a = (bytes[0+start] & 0xff) << 24;
+        int b = (bytes[1+start] & 0xff) << 16;  
+        int c = (bytes[2+start] & 0xff) << 8;  
+        int d = (bytes[3+start] & 0xff);  
+        result = a | b | c | d;
+        return result;  
+    }  
+}

--
Gitblit v1.8.0