优化 微聊数据包生成机制,兼容Gator协议的封包模式,待测。
authorSnickerSun <scy@incartech.cn>
Wed, 7 Jul 2021 16:20:19 +0000 (00:20 +0800)
committerSnickerSun <scy@incartech.cn>
Wed, 7 Jul 2021 16:20:19 +0000 (00:20 +0800)
app/src/main/java/com/enqualcomm/support/bean/VoiceContent.java
app/src/main/java/com/enqualcomm/support/bean/voicePacket.java
app/src/main/java/com/enqualcomm/support/service/Deliver.java
app/src/main/java/com/enqualcomm/support/service/SendChatMessage.java
app/src/main/java/com/enqualcomm/support/service/WeTalkMsgObserver.java
app/src/main/java/com/enqualcomm/support/utils/AESCipher.java
app/src/main/java/com/enqualcomm/support/utils/ProcessReceiver.java
app/src/main/java/com/enqualcomm/support/utils/Util.java
app/src/main/java/com/ic/protocols/protocolAPIHelper.java
app/src/main/java/com/ic/protocols/protocol_gator.java

index 893931d..2616dce 100644 (file)
@@ -56,8 +56,8 @@ public class VoiceContent extends Content {
   }\r
 \r
 \r
-  public static VoiceContent placeHolderOut(int _contactCategory, String _contactNumber, String _content,int filetype,int datatype) {\r
-    return new VoiceContent(_content, null, 1, 2, _contactCategory, _contactNumber, null, System.currentTimeMillis(),filetype,datatype);\r
+  public static VoiceContent placeHolderOut(int _contactCategory, String _contactNumber, String _preview,String _content,int filetype,int datatype) {\r
+    return new VoiceContent(_content, _preview, 1, 2, _contactCategory, _contactNumber, null, System.currentTimeMillis(),filetype,datatype);\r
   }\r
 }\r
 \r
index cd51f3c..e09fb11 100644 (file)
@@ -25,6 +25,8 @@ public class voicePacket {
 \r
     int filetype = 1;\r
     int datatype = 3;\r
+    String Sender="";\r
+    String durationHex="00";\r
     String time = null;\r
     String Name = null;\r
     String appendIndex = null;\r
@@ -43,6 +45,14 @@ public class voicePacket {
         return packetCount;\r
     }\r
 \r
+    public void setDurationHex(String duration){\r
+        durationHex=duration;\r
+    }\r
+    public String getDurationHex(){ return durationHex;}\r
+    public void setSender(String sender){\r
+        Sender=sender;\r
+    }\r
+    public String getSender(){return Sender;}\r
 \r
     public void setPacketTime(String _time) {\r
         time = _time;\r
index 11ca4f6..f44f454 100644 (file)
@@ -446,7 +446,7 @@ public class Deliver extends AbstractConnectionService {
                 ICLogger.i("voicepacket " + voicepacket.getName() + " filetype " + voicepacket.getFiletype() + " , datatype " + voicepacket.getDateType() + " " + voicepacket.getPacketTime() + " send " + (voicepacket.getCurrentIndexToSent() + 1) + "/" + voicepacket.getPacketCount());
                 if (mConnection instanceof NettyConnection) {
                     ((NettyConnection) mConnection).sendMsg("RAWPACKET",
-                            protocolAPIHelper.getVoicePacketItem(voicepacket.getPacketTime(),
+                            protocolAPIHelper.getVoicePacketItem(voicepacket.getSender(),voicepacket.getDurationHex(),voicepacket.getPacketTime(),
                                     voicepacket.getPacketCount(),
                                     (voicepacket.getCurrentIndexToSent() + 1),
                                     voicepacket.getVoicePacketWithIndex(voicepacket.getCurrentIndexToSent()).getPacketLen(),
@@ -454,7 +454,7 @@ public class Deliver extends AbstractConnectionService {
                     );
                 }
             } else {
-                ICLogger.i("voicepacket " + voicepacket.getName() + " filetype " + voicepacket.getFiletype() + " , datatype " + voicepacket.getDateType() + " " + voicepacket.getPacketTime() + " sent Done!");
+                ICLogger.i("voicepacket Sender "+voicepacket.getSender()+" duration 0x"+voicepacket.getDurationHex()+" " + voicepacket.getName() + " filetype " + voicepacket.getFiletype() + " , datatype " + voicepacket.getDateType() + " " + voicepacket.getPacketTime() + " sent Done!");
             }
             return true;
         } else if ("PhotoRemoteTaken".equals(paramStringMessage.cmd())) {
@@ -487,10 +487,10 @@ public class Deliver extends AbstractConnectionService {
 
             //创建voiceConent并添加到数据
             final VoiceContent voiceContent = VoiceContent.placeHolderOut(CONTACT_CATEGORY_GROUP,
-                    "123", msgUrl, 2, 2);
+                    "123", msgUrl,"0000", 2, 2);
 
             // 把voiceContent拆解成1024的分包
-            Util.parseToVoicePacketSent(voiceContent);
+            Util.parseToVoicePacketSent(voiceContent,1024);
             //trigger 分包发送
             if (CoreService.getInstance().getConnection() != null) {
                 //H88 专用功能拍照时检测用户体温心率
@@ -664,9 +664,9 @@ public class Deliver extends AbstractConnectionService {
                  *        *        * 1 语音——    1.监听语音      *   2.SOS语音      *      3.扩展
                  *        *          * 2 图片——  1.签到图片      *   2.指令图片      *   3.设备图片      *   4.扩展
                  */
-                final VoiceContent voiceContent = VoiceContent.placeHolderOut(CONTACT_CATEGORY_GROUP, "123", recordfilepath, 1, 1);
+                final VoiceContent voiceContent = VoiceContent.placeHolderOut(CONTACT_CATEGORY_GROUP, "123","0000", recordfilepath, 1, 1);
                 // 把voiceContent拆解成1024的分包
-                Util.parseToVoicePacketSent(voiceContent);
+                Util.parseToVoicePacketSent(voiceContent,1024);
                 //trigger 分包发送
                 if (CoreService.getInstance().getConnection() != null)
                     CoreService.getInstance().getConnection().DeliverCMDMessageToSystem("SentVoicePacket", "");
index 4807c1b..8c2c529 100644 (file)
@@ -136,7 +136,7 @@ public class SendChatMessage extends AbstractInvokeHandlerService {
                     return true;\r
 \r
                 //创建voiceConent并添加到数据\r
-                final VoiceContent voiceContent = VoiceContent.placeHolderOut(CONTACT_CATEGORY_GROUP, number, filepath, 1, 3);\r
+                final VoiceContent voiceContent = VoiceContent.placeHolderOut(CONTACT_CATEGORY_GROUP, number,"0000", filepath, 1, 3);\r
                 final Uri uri2 = runtime.getDbHelper().insertOrUpdate(voiceContent, bundle.getLong("id"));\r
 \r
                 //回复UI消息,表示已经接收到\r
@@ -150,7 +150,7 @@ public class SendChatMessage extends AbstractInvokeHandlerService {
 \r
 \r
                 // 把voiceContent拆解成1024的分包\r
-                Util.parseToVoicePacketSent(voiceContent);\r
+                Util.parseToVoicePacketSent(voiceContent,1024);\r
                 //trigger 分包发送\r
                 paramConnection.DeliverCMDMessageToSystem("SentVoicePacket", "");\r
 \r
index c6cbcbc..9838bb0 100644 (file)
@@ -48,13 +48,12 @@ public class WeTalkMsgObserver extends ContentObserver {
                 //todo:还有类型也要查询出来
                 int type = query.getInt(query.getColumnIndex("type"));
                 query.close();
-                //交给fzd协议吧,让它去发送消息
-                protocol_fzd fzd = protocolAPIHelper.getProtocolfzd_handler();
+
                 if (type == FZDDatabaseHelper.MessageType.VOICE) {
-                    fzd.sendVoice(duration, remoteNum, content, lastPathSegment);
+                    protocolAPIHelper.sendVoice(duration, remoteNum, content, lastPathSegment);
                 } else if (type == FZDDatabaseHelper.MessageType.PIC) {
                     //图片数据
-                    fzd.sendPicture(remoteNum, content, lastPathSegment);
+                    protocolAPIHelper.sendPicture(remoteNum, content, lastPathSegment);
                 }
             }
         });
index 8dec109..130de51 100644 (file)
@@ -198,7 +198,15 @@ public class AESCipher {
     return null;
   }
 
+  public static byte[] aesEncryptBytesFixedKey(byte[] bytes){
 
+    try{
+      return aesEncryptBytes(bytes, AES_KEY.getBytes(charset));
+    }catch(Exception e){
+      ICLogger.e(e.getMessage(),e);
+    }
+    return null;
+  }
   public static String aesEncryptString(String content, String key) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
     byte[] contentBytes = content.getBytes(charset);
     byte[] keyBytes = key.getBytes(charset);
index e1711a9..02bfb5d 100644 (file)
@@ -320,19 +320,19 @@ public class ProcessReceiver extends BroadcastReceiver {
              */
             if (msgType.equals("voice")) {
                 //创建voiceConent并添加到数据
-                final VoiceContent voiceContent = VoiceContent.placeHolderOut(CONTACT_CATEGORY_GROUP, msgFrom, msgUrl, 1, 3);
+                final VoiceContent voiceContent = VoiceContent.placeHolderOut(CONTACT_CATEGORY_GROUP, msgFrom,"0000", msgUrl, 1, 3);
 
                 // 把voiceContent拆解成1024的分包
-                Util.parseToVoicePacketSent(voiceContent);
+                Util.parseToVoicePacketSent(voiceContent,1024);
                 //trigger 分包发送
                 if (CoreService.getInstance().getConnection() != null)
                     CoreService.getInstance().getConnection().DeliverCMDMessageToSystem("SentVoicePacket", "");
             } else if (msgType.equals("pic")) {
                 //创建voiceConent并添加到数据
-                final VoiceContent voiceContent = VoiceContent.placeHolderOut(CONTACT_CATEGORY_GROUP, msgFrom, msgUrl, 2, 3);
+                final VoiceContent voiceContent = VoiceContent.placeHolderOut(CONTACT_CATEGORY_GROUP, msgFrom,"0000", msgUrl, 2, 3);
 
                 // 把voiceContent拆解成1024的分包
-                Util.parseToVoicePacketSent(voiceContent);
+                Util.parseToVoicePacketSent(voiceContent,1024);
                 //trigger 分包发送
                 if (CoreService.getInstance().getConnection() != null) {
 
@@ -381,11 +381,11 @@ public class ProcessReceiver extends BroadcastReceiver {
                 String msgUrl = paramIntent.getStringExtra("filepath");
                 ICLogger.i("receive taken photo to send " + msgUrl);
                 //创建voiceConent并添加到数据
-                final VoiceContent voiceContent = VoiceContent.placeHolderOut(CONTACT_CATEGORY_GROUP, msgFrom, msgUrl, 2, 2);
+                final VoiceContent voiceContent = VoiceContent.placeHolderOut(CONTACT_CATEGORY_GROUP, msgFrom,"0000", msgUrl, 2, 2);
 
 
                 // 把voiceContent拆解成1024的分包
-                Util.parseToVoicePacketSent(voiceContent);
+                Util.parseToVoicePacketSent(voiceContent,1024);
                 //trigger 分包发送
                 if (CoreService.getInstance().getConnection() != null) {
 
index d41c5ec..c3223b9 100644 (file)
@@ -1112,29 +1112,37 @@ public class Util {
         }
     }
 
-    public static boolean parseToVoicePacketSent(VoiceContent voiceContent) {
+    public static boolean parseToVoicePacketSent(VoiceContent voiceContent,int packetSize) {
 
         long filesize;
         File voicefile = new File(voiceContent.content);
         if (voicefile.exists()) {
             filesize = voicefile.length();
 
-            int count = (int) (filesize / 1024);
-            if ((filesize % 1024) > 0)
+            int count = (int) (filesize / packetSize);
+            if ((filesize % packetSize) > 0)
                 count++;
             ICLogger.i("File " + voiceContent.content + ", size " + filesize + ", count " + count + " filetype " + voiceContent.filetype + ", datatype " + voiceContent.datatype);
             voicePacket.getInstanceSent().clearPacket();
             voicePacket.getInstanceSent().setFileType(voiceContent.filetype, voiceContent.datatype);
+            voicePacket.getInstanceSent().setSender(voiceContent.contactNumber);
             try {
                 FileInputStream fis = new FileInputStream(voicefile);
-                byte[] audiobuf = new byte[1024];
+                byte[] audiobuf = new byte[packetSize];
                 for (int i = 0; i < count; i++) {
-                    int readbytes = fis.read(audiobuf, 0, 1024);
+                    int readbytes = fis.read(audiobuf, 0, packetSize);
                     voicePacket.getInstanceSent().appendVoice(voiceContent.contactNumber, "", count, i, readbytes, audiobuf);
                 }
                 fis.close();
                 voicePacket.getInstanceSent().setCurrentIndexToSent(0);
                 voicePacket.getInstanceSent().setPacketTime(TimeUtil.getSystemTime3());
+                if( voiceContent.filetype==1) //* 1 语音——       1.监听语音      *   2.SOS语音      *      3.扩展
+                {
+                    int duration=Util.getDuration(voiceContent.content);
+                    voicePacket.getInstanceSent().setDurationHex(String.format("%04X",duration));
+                }else{
+                    voicePacket.getInstanceSent().setDurationHex("0000");
+                }
                 return true;
             } catch (Exception e) {
                 e.printStackTrace();
index 52031b8..fb0d833 100644 (file)
@@ -266,7 +266,7 @@ public class protocolAPIHelper {
                 ret = null;
                 break;
             case Config.PROTOCOL_GATOR:
-                ret = null;
+                ret = protocol_gator.BP32(runtime);
                 break;
         }
         return ret;
@@ -564,8 +564,63 @@ public class protocolAPIHelper {
         }
         return ret;
     }
+    public static void sendVoice(int duration, String remoteNum, String content, String voiceId){
+        if (is_protocol_not_Initialled()) return ;
+
+        switch (Config.protocol_no) {
+            case Config.PROTOCOL_JIAI:
+                break;
+            case Config.PROTOCOL_BEEHOME:
+                break;
+            case Config.PROTOCOL_IC:
+                break;
+            case Config.PROTOCOL_FZD:
+                protocolfzd_handler.sendVoice(duration,remoteNum,content,voiceId);
+                break;
+            case Config.PROTOCOL_MQTT:
+
+                break;
+            case PROTOCOL_ANAN:
+
+                break;
+            case Config.PROTOCOL_S123:
+
+                break;
+            case Config.PROTOCOL_GATOR:
+                protocolgator_handler.sendVoicePackage(duration,remoteNum,content,voiceId);
+                break;
+        }
+
+    }
+    public static void sendPicture(String remoteNum, String imagePath, String imageId) {
+        if (is_protocol_not_Initialled()) return ;
+
+        switch (Config.protocol_no) {
+            case Config.PROTOCOL_JIAI:
+                break;
+            case Config.PROTOCOL_BEEHOME:
+                break;
+            case Config.PROTOCOL_IC:
+                break;
+            case Config.PROTOCOL_FZD:
+                protocolfzd_handler.sendPicture(remoteNum,imagePath,imageId);
+                break;
+            case Config.PROTOCOL_MQTT:
+
+                break;
+            case PROTOCOL_ANAN:
 
-    public static byte[] getVoicePacketItem(String packetTime, int count, int index, int datalen, byte[] amrdata, int filetype, int datatype) {
+                break;
+            case Config.PROTOCOL_S123:
+
+                break;
+            case Config.PROTOCOL_GATOR:
+
+                break;
+        }
+
+    }
+    public static byte[] getVoicePacketItem(String sender,String durationHEX,String packetTime, int count, int index, int datalen, byte[] amrdata, int filetype, int datatype) {
         byte[] ret = null;
         if (is_protocol_not_Initialled()) return null;
         switch (Config.protocol_no) {
@@ -609,7 +664,7 @@ public class protocolAPIHelper {
                 }
                 break;
             case Config.PROTOCOL_GATOR:
-                ret = null;
+                ret = protocol_gator.BP34_Raw(sender,packetTime,durationHEX,count,index,datalen,amrdata);
                 break;
         }
         return ret;
index 7873343..55b05f8 100644 (file)
@@ -58,6 +58,7 @@ import static com.enqualcomm.support.Constants.DIALOG_ACTION;
 import static com.enqualcomm.support.Constants.FROM_SERVER;
 import static com.enqualcomm.support.LocationClient.LOCATION_MODE;
 import static com.enqualcomm.support.bean.Contact.GROUP_ALL;
+import static com.enqualcomm.support.bean.Content.CONTACT_CATEGORY_GROUP;
 import static java.lang.Math.abs;
 
 /**
@@ -81,11 +82,11 @@ public class protocol_gator {
     private static final String CMDSPLIT = ",";
     public static final String defaultServerIP = "watch.gatorcn.com";
     public static final int defaultServerPort = 27015;
-   // public static final String defaultServerIP = "snickersun.oicp.net";
-   // public static final int defaultServerPort = 54944;
+    // public static final String defaultServerIP = "snickersun.oicp.net";
+    // public static final int defaultServerPort = 54944;
 
     public enum CMD_TYPE {
-         /* 服务器发起*/
+        /* 服务器发起*/
         AP00,//立即定位
         AP01,//设置服务器地址和端口
         AP02,//设置APN
@@ -242,7 +243,7 @@ public class protocol_gator {
         }
 
         for (CMD_TYPE key : cmdMap.keySet()) {
-            if (regexUtil.isGatorCMD(cmdMap.get(key),msg)) {
+            if (regexUtil.isGatorCMD(cmdMap.get(key), msg)) {
                 ICLogger.i("found gator cmd keyid=" + key + " ,keyname=" + cmdMap.get(key));
                 return cmdMap.get(key);
             }
@@ -262,15 +263,30 @@ public class protocol_gator {
 
     private Handler mHandler = null;
 
-    private static String encrepteMsg(String msg){
-        String encreptedStr="";
-        String encreptionMSGHeader="GT";
-        encreptedStr=AESCipher.aesEncryptStringFixedKey(msg);
-        String len= String.format("%04X",encreptedStr.length()+8);
-        return encreptionMSGHeader+len+"01"+encreptedStr;
+    private static String encrepteMsg(String msg) {
+        String encreptedStr = "";
+        String encreptionMSGHeader = "GT";
+        encreptedStr = AESCipher.aesEncryptStringFixedKey(msg);
+        String len = String.format("%04X", encreptedStr.length() + 8);
+        return encreptionMSGHeader + len + "01" + encreptedStr;
+    }
+    private static byte[] encrepteMsgBytes(byte[] msgbytes) {
+
+        String encreptionMSGHeader = "GT";
+        byte[] encryptdata = AESCipher.aesEncryptBytesFixedKey(msgbytes);
+        int len=encryptdata.length+8;
+        String encdatalen = String.format("%04X01", len);
+        byte[] sentbuf = new byte[len];
+
+        System.arraycopy(encreptionMSGHeader.getBytes(),0,sentbuf,0,2);
+        System.arraycopy(encdatalen.getBytes(),0,sentbuf,2,6);
+        System.arraycopy(encryptdata, 0, sentbuf, 8, encryptdata.length);
+
+        return sentbuf;
     }
+
     //根据协议添加头尾以及IMEI号
-    private static String AddHeader(Runtime runtime,String msg){
+    private static String AddHeader(Runtime runtime, String msg) {
         /*
         (    CHAR            1
         %04X   HEX_STRING      4
@@ -280,7 +296,7 @@ public class protocol_gator {
            )  CHAR             1
            */
 
-        String len= String.format("%04X",1+4+4+15+msg.length()+1);
+        String len = String.format("%04X", 1 + 4 + 4 + 15 + msg.length() + 1);
         return new StringBuffer(CMDHEADER).append(len).append("0106").append(runtime.IMEI()).append(msg).append(
                 CMDEND).toString();
 
@@ -292,7 +308,7 @@ public class protocol_gator {
         StringMessage sm = new StringMessage(new String[]{cmdName, msg});
         //用此函数设置要发送的内容
         sm.refresh(encrepteMsg(msg));
-       // sm.refresh((msg));
+        // sm.refresh((msg));
         //设置信息创建时间
         sm.setDate(TimeUtil.getSystemDateYYMMDD(), TimeUtil.getSystemTimeHHmmss());
         return sm;
@@ -319,7 +335,7 @@ public class protocol_gator {
         if (cmdbuf.toString().endsWith(CMDEND)) {
             iscmdComplete = true;
         }
-        String[] cmdlist = cmd_msgbuf.split("\\"+CMDEND);
+        String[] cmdlist = cmd_msgbuf.split("\\" + CMDEND);
         int listlen = cmdlist.length;
         ICLogger.d("listlen " + listlen);
         /**
@@ -332,17 +348,17 @@ public class protocol_gator {
         }
         for (int i = 0; i < listlen; i++) {
             for (CMD_TYPE key : cmdMap.keySet()) {
-                if (cmdlist[i].length()>=24 && regexUtil.isGatorCMD(cmdMap.get(key),cmdlist[i].substring(0,24)) ) {
+                if (cmdlist[i].length() >= 24 && regexUtil.isGatorCMD(cmdMap.get(key), cmdlist[i].substring(0, 24))) {
                     ICLogger.d("found gator cmd keyid=" + key + " ,keyname=" + cmdMap.get(key) + " ,  " + cmdlist[i]);
                     if (key == CMD_TYPE.AP12) {
                         //如果是BP12则 后面的数据是音频,需要保留
 //                        byte[] amrBuf;
 //                        int amrLen = getBP28Amrlen(cmdlist[i]);
 //                        if (bytes.length > amrLen) {
-                            handleCmd(key, cmdlist[i], bytes);
+                        handleCmd(key, cmdlist[i], bytes);
 //                        }
                     } else {
-                        String cmdi=cmdlist[i].trim().replace(CMDHEADER,"").replace(CMDEND,"");
+                        String cmdi = cmdlist[i].trim().replace(CMDHEADER, "").replace(CMDEND, "");
                         handleCmd(key, cmdi);
                     }
                 }
@@ -394,15 +410,16 @@ public class protocol_gator {
     }
 
     //回复服务器专用通用接口
-    public StringMessage BPXX_REPLY(Runtime ds,CMD_TYPE type,String index,boolean success){
-        StringMessage ret=null;
+    public StringMessage BPXX_REPLY(Runtime ds, CMD_TYPE type, String index, boolean success) {
+        StringMessage ret = null;
         if (success) {
-            ret = genStringMessage(cmdMap.get(type), AddHeader(ds, cmdMap.get(type) + index+"1"));
-        }else{
-            ret = genStringMessage(cmdMap.get(type), AddHeader(ds, cmdMap.get(type) + index+"0"));
+            ret = genStringMessage(cmdMap.get(type), AddHeader(ds, cmdMap.get(type) + index + "1"));
+        } else {
+            ret = genStringMessage(cmdMap.get(type), AddHeader(ds, cmdMap.get(type) + index + "0"));
         }
         return ret;
     }
+
     /*登录*/
     public static StringMessage BP00(Runtime ds) {
         //示例数据:BP00,AAAA,BB,CC
@@ -418,26 +435,26 @@ public class protocol_gator {
         //7:   4格显示
         //CC:MCCMNC
 
-        int batstat=0;
-        int batlevel=ds.getBatterylevel();
-        if (batlevel>0 && batlevel<= 15){
-            batstat=3;
-        }else if (batlevel>15 && batlevel<= 35){
-            batstat=4;
-        }else if (batlevel>35 && batlevel<= 55){
-            batstat=5;
-        }else if (batlevel>55 && batlevel<= 85){
-            batstat=6;
-        }else {
-            batstat=7;
+        int batstat = 0;
+        int batlevel = ds.getBatterylevel();
+        if (batlevel > 0 && batlevel <= 15) {
+            batstat = 3;
+        } else if (batlevel > 15 && batlevel <= 35) {
+            batstat = 4;
+        } else if (batlevel > 35 && batlevel <= 55) {
+            batstat = 5;
+        } else if (batlevel > 55 && batlevel <= 85) {
+            batstat = 6;
+        } else {
+            batstat = 7;
         }
-        String msg=new StringBuffer(cmdMap.get(CMD_TYPE.BP00)).append(CMDSPLIT)
+        String msg = new StringBuffer(cmdMap.get(CMD_TYPE.BP00)).append(CMDSPLIT)
                 .append(DeviceInfoUtil.getSWVersionDisplayName()).append(CMDSPLIT)
                 .append(batstat).append(CMDSPLIT)
                 .append(ds.getMccAndMnc())
                 .toString();
 
-        return genStringMessage(cmdMap.get(CMD_TYPE.BP00), AddHeader(ds,msg));
+        return genStringMessage(cmdMap.get(CMD_TYPE.BP00), AddHeader(ds, msg));
     }
 
     //时间同步,等同于登录成功回复
@@ -448,10 +465,10 @@ public class protocol_gator {
         if (msg.length == 5) {
             log("handleBP00", "Set Datetime " + msg[1] + msg[2]);
             log("handleBP00", "Set TimeZone " + msg[3]);
-            String index=msg[4];
+            String index = msg[4];
             try {
-                Date datetime = TimeUtil.parseDatetiime("20"+msg[1]+msg[2]);
-              //  Date timezone = TimeUtil.parsetiime(msg[3].substring(1));
+                Date datetime = TimeUtil.parseDatetiime("20" + msg[1] + msg[2]);
+                //  Date timezone = TimeUtil.parsetiime(msg[3].substring(1));
 
                 if (datetime != null) {
                     ICLogger.i("===" + TimeUtil.getDefaultTimeZone());
@@ -460,14 +477,14 @@ public class protocol_gator {
                     ICLogger.i("===" + TimeUtil.getDefaultTimeZone());
                     TimeUtil.setSysDateTime(runtime.getContextProxy().context, datetime, msg[3], true);
                     ICLogger.i("===" + TimeUtil.getDefaultTimeZone());
-                    connection.send(BPXX_REPLY(runtime,CMD_TYPE.BP03,index,true));
-                }else{
-                    connection.send(BPXX_REPLY(runtime,CMD_TYPE.BP03,index,false));
+                    connection.send(BPXX_REPLY(runtime, CMD_TYPE.BP03, index, true));
+                } else {
+                    connection.send(BPXX_REPLY(runtime, CMD_TYPE.BP03, index, false));
                 }
             } catch (Exception e) {
                 ICLogger.e(e.getMessage(), e);
 
-                connection.send(BPXX_REPLY(runtime,CMD_TYPE.BP03,index,false));
+                connection.send(BPXX_REPLY(runtime, CMD_TYPE.BP03, index, false));
             }
 //            Set Datetime 20200505112734
 //            Set TimeZone 8
@@ -477,8 +494,8 @@ public class protocol_gator {
     }
 
     //设置亲情号码
-    public void handleAP06(Runtime ds,Connection connection,String cmd) {
-        log("AP06 设置亲情号码 "+cmd);
+    public void handleAP06(Runtime ds, Connection connection, String cmd) {
+        log("AP06 设置亲情号码 " + cmd);
 /*
 消息内容   Type取值:0-4
 0表示:其他人
@@ -499,58 +516,60 @@ uncle:13141516175
 响应:      失败:(002E0106357593060153353BP0600000000000000050)
 成功:(002E0106357593060153353BP0600000000000000051)
  */
-        StringBuffer sb=new StringBuffer();
-        String cmdlist[]=cmd.split(",");
-        if (cmdlist.length==2){
-            sb.append("server msg index "+cmdlist[1]+"\n");
-            String cmdlist1[]=cmdlist[0].split("#");
-            int index=0;
-            if(cmdlist1.length%3==1) {
+        StringBuffer sb = new StringBuffer();
+        String cmdlist[] = cmd.split(",");
+        if (cmdlist.length == 2) {
+            sb.append("server msg index " + cmdlist[1] + "\n");
+            String cmdlist1[] = cmdlist[0].split("#");
+            int index = 0;
+            if (cmdlist1.length % 3 == 1) {
                 for (int i = 1; i < cmdlist1.length; i += 3) {
-                    String number= cmdlist1[i];
-                    String name=cmdlist1[i+1];
-                    String type=cmdlist1[i+2];
+                    String number = cmdlist1[i];
+                    String name = cmdlist1[i + 1];
+                    String type = cmdlist1[i + 2];
                     index++;
-                    sb.append(index+" "+name+" "+number + " " + type+"\n");
+                    sb.append(index + " " + name + " " + number + " " + type + "\n");
                 }
 
-            }else{
+            } else {
                 ICLogger.e("AP06 format error1 !");
-                connection.send(BPXX_REPLY(ds,CMD_TYPE.BP06,cmdlist[1],false));
+                connection.send(BPXX_REPLY(ds, CMD_TYPE.BP06, cmdlist[1], false));
             }
 
             ICLogger.d(sb.toString());
-            connection.send(BPXX_REPLY(ds,CMD_TYPE.BP06,cmdlist[1],true));
-        }else{
+            connection.send(BPXX_REPLY(ds, CMD_TYPE.BP06, cmdlist[1], true));
+        } else {
             ICLogger.e("AP06 format error!");
-            connection.send(BPXX_REPLY(ds,CMD_TYPE.BP06,cmdlist[1],false));
+            connection.send(BPXX_REPLY(ds, CMD_TYPE.BP06, cmdlist[1], false));
         }
 
 
     }
-    public void handleAP07(Runtime ds,Connection connection,String cmd) {
+
+    public void handleAP07(Runtime ds, Connection connection, String cmd) {
 //        (002A357593060153353AP07,0000000000000006) 平台向终端请求清空所有的亲情号码
-        String cmdlist[]=cmd.split(CMDSPLIT);
-        if(cmdlist.length==2){
-            log("AP07 清除亲情号码 " );
-            connection.send(BPXX_REPLY(ds,CMD_TYPE.BP07,cmdlist[1],true));
-        }else{
+        String cmdlist[] = cmd.split(CMDSPLIT);
+        if (cmdlist.length == 2) {
+            log("AP07 清除亲情号码 ");
+            connection.send(BPXX_REPLY(ds, CMD_TYPE.BP07, cmdlist[1], true));
+        } else {
             ICLogger.e("AP07 format error!");
         }
     }
+
     //重启
-    public void handleAP08(Runtime ds,Connection connection,String cmd) {
+    public void handleAP08(Runtime ds, Connection connection, String cmd) {
 //        (002A357593060153353AP08,0000000000000007)
-        String cmdlist[]=cmd.split(CMDSPLIT);
-        if(cmdlist.length==2){
-            log("AP08 重启设备 " );
-            connection.send(BPXX_REPLY(ds,CMD_TYPE.BP08,cmdlist[1],true));
-        }else{
+        String cmdlist[] = cmd.split(CMDSPLIT);
+        if (cmdlist.length == 2) {
+            log("AP08 重启设备 ");
+            connection.send(BPXX_REPLY(ds, CMD_TYPE.BP08, cmdlist[1], true));
+        } else {
             ICLogger.e("AP08 format error!");
         }
     }
 
-    public void handleAP09(Runtime ds,Connection connection,String cmd) {
+    public void handleAP09(Runtime ds, Connection connection, String cmd) {
 
 // AP09,A,B,C,YYMMDD,HHMMSS
 //A:表示删除、添加(修改)闹钟功能,分别用0、1表示(类型%d)
@@ -562,80 +581,81 @@ uncle:13141516175
 //增加(修改)一条索引为0的闹铃,每天15:29:00响铃
 //(002E357593060153353AP09,0,0,0000000000000008)
 //删除一条索引为0的闹铃
-        String cmdlist[]=cmd.split(CMDSPLIT);
-        if(cmdlist.length==7){
+        String cmdlist[] = cmd.split(CMDSPLIT);
+        if (cmdlist.length == 7) {
 
 
-            log("AP09 设置闹铃 " );
+            log("AP09 设置闹铃 ");
 
-            connection.send(BPXX_REPLY(ds,CMD_TYPE.BP09,cmdlist[6],true));
-        }else if(cmdlist.length==4){
+            connection.send(BPXX_REPLY(ds, CMD_TYPE.BP09, cmdlist[6], true));
+        } else if (cmdlist.length == 4) {
 
-            log("AP09 删除闹铃 " );
+            log("AP09 删除闹铃 ");
 
-            connection.send(BPXX_REPLY(ds,CMD_TYPE.BP09,cmdlist[3],true));
-        }else{
+            connection.send(BPXX_REPLY(ds, CMD_TYPE.BP09, cmdlist[3], true));
+        } else {
             ICLogger.e("AP09 format error!");
         }
     }
 
-    public void handleAP10(Runtime ds,Connection connection,String cmd) {
+    public void handleAP10(Runtime ds, Connection connection, String cmd) {
 
 //    (002C357593060153353AP10,1,0000000000000009)
 //    开启静音模式
 //            (002C357593060153353AP10,0,0000000000000009)
 //    关闭静音模式
 
-        String cmdlist[]=cmd.split(CMDSPLIT);
-        if (cmdlist.length==3){
-            String index=cmdlist[2];
-            boolean enableSilentMode=false;
-            if(cmdlist[1].equals("1")){
-                enableSilentMode=true;
+        String cmdlist[] = cmd.split(CMDSPLIT);
+        if (cmdlist.length == 3) {
+            String index = cmdlist[2];
+            boolean enableSilentMode = false;
+            if (cmdlist[1].equals("1")) {
+                enableSilentMode = true;
             }
-            ICLogger.d(" enable SilentMode  "+enableSilentMode);
-            connection.send(BPXX_REPLY(ds,CMD_TYPE.BP10,index,true));
-        }else {
+            ICLogger.d(" enable SilentMode  " + enableSilentMode);
+            connection.send(BPXX_REPLY(ds, CMD_TYPE.BP10, index, true));
+        } else {
             ICLogger.e("AP10 format error");
         }
     }
 
 
-    public static StringMessage BP11(Runtime ds,String MSGType,String MSGCount){
+    public static StringMessage BP11(Runtime ds, String MSGType, String MSGCount) {
         //(00250106357593060153353BP11,AP12,01)
         //表示请求服务器下载1条微聊信息
         //(00250106357593060153353BP11,AP23,01)
         //表示请求服务器下载1条亲情号码自拍图片信息
-        StringMessage ret=null;
-        StringBuilder sb=new StringBuilder(cmdMap.get(CMD_TYPE.BP11) );
+        StringMessage ret = null;
+        StringBuilder sb = new StringBuilder(cmdMap.get(CMD_TYPE.BP11));
         sb.append(CMDSPLIT).append(MSGType).append(CMDSPLIT).append(MSGCount);
         ret = genStringMessage(cmdMap.get(CMD_TYPE.BP11), AddHeader(ds, sb.toString()));
         return ret;
     }
+
     //服务器通知有消息待发送
-    public void handleAP11(Runtime ds,Connection connection,String cmd) {
+    public void handleAP11(Runtime ds, Connection connection, String cmd) {
 //        (0021357593060153353AP11,AP12,02)
 //        表示当前服务器有2条新微聊信息待接收
 //
 //                (0021357593060153353AP11,AP23,01)
 //        表示当前服务器有1条亲情号码自拍图片信息待接收
-        String cmdlist[]=cmd.split(CMDSPLIT);
-        if (cmdlist.length==3){
-            String msgcount=cmdlist[2];
+        String cmdlist[] = cmd.split(CMDSPLIT);
+        if (cmdlist.length == 3) {
+            String msgcount = cmdlist[2];
 
-           String msgType=cmdlist[1];
+            String msgType = cmdlist[1];
 
-            ICLogger.d(" 服务器有  "+msgcount+"条 "+msgType+" 消息待接收。");
+            ICLogger.d(" 服务器有  " + msgcount + "条 " + msgType + " 消息待接收。");
 
-            connection.send(BP11(ds,msgType,"01"));
-        }else {
+            connection.send(BP11(ds, msgType, "01"));
+        } else {
             ICLogger.e("AP11 format error");
         }
 
 
     }
 
-    public static StringMessage BP12(Runtime ds,String sourceNumber,int count, int index, String time,boolean success){
+    public static StringMessage BP12(Runtime ds, String sourceNumber, int count, int index, String time, boolean success) {
 //        失败:
 //        (00400106357593060153353BP12,13026618172,1704131633000000,6,1,0)
 //        (00410106357593060153353BP12,13026618172,1704131633000000,6,1,-1)
@@ -643,14 +663,14 @@ uncle:13141516175
 //                -1:表示13026618172不是手表的情亲号码
 //        成功:
 //        (00400106357593060153353BP12,13026618172,1704131633000000,6,1,1)
-        StringMessage ret=null;
-        StringBuilder sb=new StringBuilder(cmdMap.get(CMD_TYPE.BP12) );
+        StringMessage ret = null;
+        StringBuilder sb = new StringBuilder(cmdMap.get(CMD_TYPE.BP12));
 
         sb.append(CMDSPLIT).append(sourceNumber).append(CMDSPLIT).append(time);
         sb.append(CMDSPLIT).append(count).append(CMDSPLIT).append(index).append(CMDSPLIT);
-        if(success){
+        if (success) {
             sb.append(1);
-        }else{
+        } else {
             sb.append(0);
         }
         ret = genStringMessage(cmdMap.get(CMD_TYPE.BP12), AddHeader(ds, sb.toString()));
@@ -700,6 +720,7 @@ uncle:13141516175
         }
         return (int) ((duration / 1000) + 1);
     }
+
     private void message2Db(String remoteId, String amrFilepath, int type) {
 //        try {
 //            //通知有消息到
@@ -739,7 +760,7 @@ uncle:13141516175
     }
 
     //服务器下发微聊消息
-    public void handleAP12(Runtime ds,Connection connection,byte[]  bytes) {
+    public void handleAP12(Runtime ds, Connection connection, byte[] bytes) {
 //        AP12,亲情号码,YYMMDDHHMMSSSSSS,分包总数(%d),当分包索引(%d),分包语音数据长度(%03d<=900)+数据
 //        (03C3357593060153353AP12,13026618172,1704131633000000,6,1,700,数据)
 //        AP12:命令字符
@@ -748,26 +769,26 @@ uncle:13141516175
 //        6:语音包分包总数
 //        1:当前包数,第一包为1,第二包为2,。。。。。。   同一个语音包的语音时间相同
 //        700:当前分包的语音数据长度,每个音频数据包大小为700字节,最后一包不足700的取实际字节数
-        String cmd=new String(bytes);
-        String cmdlist[]=cmd.split(CMDSPLIT);
-        if (cmdlist.length>=7){
-            String time=cmdlist[2];
-            String sourceNumb=cmdlist[1];
-            String packagescount=cmdlist[3];
-            String packageindex=cmdlist[4];
-            String packageslen=cmdlist[5];
-            int index=0;
-            int count=0;
-            int ipackagelen=0;
+        String cmd = new String(bytes);
+        String cmdlist[] = cmd.split(CMDSPLIT);
+        if (cmdlist.length >= 7) {
+            String time = cmdlist[2];
+            String sourceNumb = cmdlist[1];
+            String packagescount = cmdlist[3];
+            String packageindex = cmdlist[4];
+            String packageslen = cmdlist[5];
+            int index = 0;
+            int count = 0;
+            int ipackagelen = 0;
             try {
-                index=Integer.parseInt(packageindex);
-                count=Integer.parseInt(packagescount);
-                ipackagelen=Integer.parseInt(packageslen);
-            }catch (Exception e){
-                ICLogger.e(e.getMessage(),e);
+                index = Integer.parseInt(packageindex);
+                count = Integer.parseInt(packagescount);
+                ipackagelen = Integer.parseInt(packageslen);
+            } catch (Exception e) {
+                ICLogger.e(e.getMessage(), e);
             }
-            ICLogger.d("receive msg from "+sourceNumb+" "+index+" of "+count + " len "+packageslen+" time "+time);
-            connection.send(BP12(ds,sourceNumb,count,index,time,true));
+            ICLogger.d("receive msg from " + sourceNumb + " " + index + " of " + count + " len " + packageslen + " time " + time);
+            connection.send(BP12(ds, sourceNumb, count, index, time, true));
             byte packetData[] = Util.subArray(bytes, cmdlist[0].length() + cmdlist[1].length() + cmdlist[2].length() + cmdlist[3].length() + cmdlist[4].length() + cmdlist[5].length() + 6, bytes.length - 1);
 
             voicePacket.getInstance().appendVoice(sourceNumb, time, count, index, ipackagelen, packetData);
@@ -790,10 +811,11 @@ uncle:13141516175
 //                runtime.getContextProxy().sendBroadcast(ACTION_IMESSAGE, runtime);
                 connection.DeliverCMDMessageToSystem("NewVoice", amrFilepath);//通知下面线程状态变化
             }
-        }else {
+        } else {
             ICLogger.e("AP12 format error");
         }
     }
+
     public static StringMessage BP33(Runtime ds) {
 //(00520106357593060153353BP33,0,000000FF,5,46000024820000DE127,151028,163100,0,0,0)
 //报警类型:0x0 无报警;0x02 SOS报警;0x08 电池低电量报警;0x20 设备脱离
@@ -801,22 +823,22 @@ uncle:13141516175
 //电量等级:5
 //基站接入点:46000024820000DE127
 //日期时间:151028,163100
-        int batstat=0;
-        int batlevel=ds.getBatterylevel();
-        if (batlevel>0 && batlevel<= 15){
-            batstat=1;
-        }else if (batlevel>15 && batlevel<= 35){
-            batstat=2;
-        }else if (batlevel>35 && batlevel<= 55){
-            batstat=3;
-        }else if (batlevel>55 && batlevel<= 85){
-            batstat=4;
-        }else {
-            batstat=5;
+        int batstat = 0;
+        int batlevel = ds.getBatterylevel();
+        if (batlevel > 0 && batlevel <= 15) {
+            batstat = 1;
+        } else if (batlevel > 15 && batlevel <= 35) {
+            batstat = 2;
+        } else if (batlevel > 35 && batlevel <= 55) {
+            batstat = 3;
+        } else if (batlevel > 55 && batlevel <= 85) {
+            batstat = 4;
+        } else {
+            batstat = 5;
         }
-        String netstat=ds.getGatorLBSData();
+        String netstat = ds.getGatorLBSData();
 
-        String msg=new StringBuffer(cmdMap.get(CMD_TYPE.BP33)).append(CMDSPLIT)
+        String msg = new StringBuffer(cmdMap.get(CMD_TYPE.BP33)).append(CMDSPLIT)
                 .append(ds.getGatorAlarmType()).append(CMDSPLIT)
                 .append(String.format("%08X", ds.getTotalStepCount())).append(CMDSPLIT)
                 .append(batstat).append(CMDSPLIT)
@@ -826,17 +848,18 @@ uncle:13141516175
                 .append("0,0,0")
                 .toString();
 
-        StringMessage ret = genStringMessage(cmdMap.get(CMD_TYPE.BP33), AddHeader(ds,msg));
+        StringMessage ret = genStringMessage(cmdMap.get(CMD_TYPE.BP33), AddHeader(ds, msg));
 
         return ret;
     }
 
 
-    public void handleAP04(Runtime ds,Connection connection,String cmd) {
+    public void handleAP04(Runtime ds, Connection connection, String cmd) {
         log("AP04读取版本,返回BP00");
         connection.send(BP00(ds));
     }
-    public void handleAP00(Connection connection,Runtime ds,String cmd) {
+
+    public void handleAP00(Connection connection, Runtime ds, String cmd) {
         log("AP00立即定位,返回BP30");
     }
 
@@ -845,31 +868,31 @@ uncle:13141516175
      * @param ds
      * @return
      */
-    public static StringMessage BP30(Runtime ds){
-        StringBuilder sb=new StringBuilder(cmdMap.get(CMD_TYPE.BP30)).append(CMDSPLIT);
-
-        int batstat=0;
-        int batlevel=ds.getBatterylevel();
-        if (batlevel>0 && batlevel<= 15){
-            batstat=1;
-        }else if (batlevel>15 && batlevel<= 35){
-            batstat=2;
-        }else if (batlevel>35 && batlevel<= 55){
-            batstat=3;
-        }else if (batlevel>55 && batlevel<= 85){
-            batstat=4;
-        }else {
-            batstat=5;
+    public static StringMessage BP30(Runtime ds) {
+        StringBuilder sb = new StringBuilder(cmdMap.get(CMD_TYPE.BP30)).append(CMDSPLIT);
+
+        int batstat = 0;
+        int batlevel = ds.getBatterylevel();
+        if (batlevel > 0 && batlevel <= 15) {
+            batstat = 1;
+        } else if (batlevel > 15 && batlevel <= 35) {
+            batstat = 2;
+        } else if (batlevel > 35 && batlevel <= 55) {
+            batstat = 3;
+        } else if (batlevel > 55 && batlevel <= 85) {
+            batstat = 4;
+        } else {
+            batstat = 5;
         }
         //类型    "LBS"   "GPS"  "WiFi"
         String LocationType = ds.getLocationInstance().getLocationType();
-        if(LocationType.equals("LBS")) {
+        if (LocationType.equals("LBS")) {
 
-            if(ds.getGatorLBSMultiStationData().isEmpty()){
+            if (ds.getGatorLBSMultiStationData().isEmpty()) {
                 //no available data
                 ICLogger.e("没有有效定位信息");
                 return null;
-            }else{
+            } else {
      /*   基站定位:
 (008E0106357593060153353BP30,L,2,000000FF,5,1,4,46000024820000DE127,46000024820000DDF1A,46000024820000DEB0D,46000024820000F160B,150728,152900)
 SOS报警上行基站位置消息,步数为255步,电量等级5,服务器需要下发经纬度信息给手表,定位数据采集时间为 2015 年 07 月 28 日,当地时间15:29:00.采集到的基站数为4个,第一个是主基站,其余3个为辅助基站
@@ -892,9 +915,9 @@ SOS报警上行基站位置消息,步数为255步,电量等级5,服务器需
                 sb.append(TimeUtil.getSystemTimeHHmmss());
             }
 
-        }else if(LocationType.equals("WiFi")) {
+        } else if (LocationType.equals("WiFi")) {
 
-            if(ds.getLBSMultiStationData().isEmpty()){
+            if (ds.getLBSMultiStationData().isEmpty()) {
         /*WIFI定位:
 (00A60106357593060153353BP30,W,2,000000FF,5,1,150728,152900,3,08,wifi2462,1C:78:57:08:A5:CA,-88,05,HDB-H,D8:15:0D:5C:4D:74,-87,0D,WWW.CXGPS.COM,D8:15:0D:A8:E8:DE,-86)
 SOS报警上行WIFI数据,步数为255步,电量等级5,服务器需要下发经纬度信息给手表,数据采集时间2015年7月28日,当地时间15:29:00,共3条数据(最多6条),分别由SSID长度(%02X),SSID,MAC地址,RSSI组成
@@ -911,7 +934,7 @@ SOS报警上行WIFI数据,步数为255步,电量等级5,服务器需要下
                 sb.append(TimeUtil.getSystemDateYYMMDD()).append(CMDSPLIT);
                 sb.append(TimeUtil.getSystemTimeHHmmss()).append(CMDSPLIT);
 
-            }else{
+            } else {
          /*WIFI、LBS混合定位:
 (00F80106357593060153353BP30,M,2,000000FF,5,1,150728,152900,4,46000024820000DE127,46000024820000DDF1A,46000024820000DEB0D,46000024820000F160B,3,08,wifi2462,1C:78:57:08:A5:CA,-88,05,HDB-H,D8:15:0D:5C:4D:74,-87,0D,WWW.CXGPS.COM,D8:15:0D:A8:E8:DE,-86)
 SOS报警上行WIFI、LBS混合定位数据,步数为255步,电量等级5,数据采集时间2015年7月28日,当地时间15:29:00,基站数为4个,第一个是主基站,其余3个为辅助基站,WIFI共3条数据(最多6条),分别由SSID长度(%02X),SSID,MAC地址,RSSI组成
@@ -931,7 +954,7 @@ SOS报警上行WIFI、LBS混合定位数据,步数为255步,电量等级5,数
 
             }
 
-        }else if(LocationType.equals("GPS")){
+        } else if (LocationType.equals("GPS")) {
         /*GPS定位:
         (006E0106357593060153353BP30,G,2,000000FF,5,46000024820000DE127,150728A2934.0133N10627.2544E000.0141830309.62)
                 SOS报警上行GPS位置数据,步数为255步,电量等级5,当前基站接入的为:46000024820000DE127
@@ -945,96 +968,226 @@ SOS报警上行WIFI、LBS混合定位数据,步数为255步,电量等级5,数
             sb.append(ds.getGatorLBSData()).append(CMDSPLIT);
             sb.append(ds.getGatorGPSLocationData());
 
-        }else{
+        } else {
             //生成数据错误,返回null
             return null;
         }
 
-        StringMessage ret = genStringMessage(cmdMap.get(CMD_TYPE.BP30), AddHeader(ds,sb.toString()));
+        StringMessage ret = genStringMessage(cmdMap.get(CMD_TYPE.BP30), AddHeader(ds, sb.toString()));
         return ret;
     }
 
 
     //接收服务器定位后坐标
-    public void handleAP14(Runtime ds, Connection connection,String cmd){
+    public void handleAP14(Runtime ds, Connection connection, String cmd) {
         ICLogger.d(cmd);
         //(0056357593060153353AP1424.772816,121.022636,160,2015,11,12,08,00,00,0000000000000010)
 //        AP14+(Lat,Long,Alt,YYYY,MM,DD,hh,mm,ss)
-        String cmdlist[]=cmd.split(CMDSPLIT);
-        if (cmdlist.length==10){
-            String index=cmdlist[9];
-            String lat=cmdlist[0];
-            String lon=cmdlist[1];
-            String alt=cmdlist[2];
-            String time=cmdlist[3]+"-"+cmdlist[4]+"-"+cmdlist[5]+" "+cmdlist[6]+":"+cmdlist[7]+":"+cmdlist[8];
+        String cmdlist[] = cmd.split(CMDSPLIT);
+        if (cmdlist.length == 10) {
+            String index = cmdlist[9];
+            String lat = cmdlist[0];
+            String lon = cmdlist[1];
+            String alt = cmdlist[2];
+            String time = cmdlist[3] + "-" + cmdlist[4] + "-" + cmdlist[5] + " " + cmdlist[6] + ":" + cmdlist[7] + ":" + cmdlist[8];
             try {
-                lat = lat.substring(lat.indexOf("AP14")+4);
-            }catch (Exception e){
-                ICLogger.e(e.getMessage(),e);
+                lat = lat.substring(lat.indexOf("AP14") + 4);
+            } catch (Exception e) {
+                ICLogger.e(e.getMessage(), e);
             }
-            ICLogger.d("lat "+lat+" lon "+lon + " "+alt+" time "+time);
-            connection.send(BPXX_REPLY(ds,CMD_TYPE.BP14,index,true));
-        }else {
+            ICLogger.d("lat " + lat + " lon " + lon + " " + alt + " time " + time);
+            connection.send(BPXX_REPLY(ds, CMD_TYPE.BP14, index, true));
+        } else {
             ICLogger.e("AP14 format error");
         }
     }
 
 
     //开关机控制设置消息 AP15
-    public void handleAP15(Runtime ds, Connection connection,String cmd){
+    public void handleAP15(Runtime ds, Connection connection, String cmd) {
         ICLogger.d(cmd);
         //(002C357593060153353AP15,1,0000000000000011)
         //表示允许手表手动关机
         //(002C357593060153353AP15,0,0000000000000011)
         //表示不允许手表手动关机
-        String cmdlist[]=cmd.split(CMDSPLIT);
-        if (cmdlist.length==3){
-            String index=cmdlist[2];
-            boolean enableUserPoweroff=false;
-            if(cmdlist[1].equals("1")){
-                enableUserPoweroff=true;
+        String cmdlist[] = cmd.split(CMDSPLIT);
+        if (cmdlist.length == 3) {
+            String index = cmdlist[2];
+            boolean enableUserPoweroff = false;
+            if (cmdlist[1].equals("1")) {
+                enableUserPoweroff = true;
             }
-            ICLogger.d(" enable UserPoweroff  "+enableUserPoweroff);
-            connection.send(BPXX_REPLY(ds,CMD_TYPE.BP15,index,true));
-        }else {
+            ICLogger.d(" enable UserPoweroff  " + enableUserPoweroff);
+            connection.send(BPXX_REPLY(ds, CMD_TYPE.BP15, index, true));
+        } else {
             ICLogger.e("AP15 format error");
         }
     }
-//    服务器激活SOS模式消息 AP16
-    public void handleAP16(Runtime ds, Connection connection,String cmd){
+
+    //    服务器激活SOS模式消息 AP16
+    public void handleAP16(Runtime ds, Connection connection, String cmd) {
         ICLogger.d(cmd);
         //服务器激活SOS模式:
         //(002C357593060153353AP16,1,0000000000000012)
 
-        String cmdlist[]=cmd.split(CMDSPLIT);
-        if (cmdlist.length==3){
-            String index=cmdlist[2];
-            boolean enableUserSOS=false;
-            if(cmdlist[1].equals("1")){
-                enableUserSOS=true;
+        String cmdlist[] = cmd.split(CMDSPLIT);
+        if (cmdlist.length == 3) {
+            String index = cmdlist[2];
+            boolean enableUserSOS = false;
+            if (cmdlist[1].equals("1")) {
+                enableUserSOS = true;
             }
-            ICLogger.d(" enable enable UserSOS  "+enableUserSOS);
-            connection.send(BPXX_REPLY(ds,CMD_TYPE.BP16,index,true));
-        }else {
+            ICLogger.d(" enable enable UserSOS  " + enableUserSOS);
+            connection.send(BPXX_REPLY(ds, CMD_TYPE.BP16, index, true));
+        } else {
             ICLogger.e("AP16 format error");
         }
     }
-//    手表名字设置消息 AP18
-    public void handleAP18(Runtime ds, Connection connection,String cmd){
+
+    //    手表名字设置消息 AP18
+    public void handleAP18(Runtime ds, Connection connection, String cmd) {
         ICLogger.d(cmd);
         //(0031357593060153353AP18,BAOBAO,0000000000000013)
 
-        String cmdlist[]=cmd.split(CMDSPLIT);
-        if (cmdlist.length==3){
-            String index=cmdlist[2];
-            String watchName=cmdlist[1];
+        String cmdlist[] = cmd.split(CMDSPLIT);
+        if (cmdlist.length == 3) {
+            String index = cmdlist[2];
+            String watchName = cmdlist[1];
 
-            ICLogger.d("set watchName  "+watchName);
-            connection.send(BPXX_REPLY(ds,CMD_TYPE.BP18,index,true));
-        }else {
+            ICLogger.d("set watchName  " + watchName);
+            connection.send(BPXX_REPLY(ds, CMD_TYPE.BP18, index, true));
+        } else {
             ICLogger.e("AP18 format error");
         }
     }
+
+    public void handleAP21(Runtime runtime, Connection connection, String cmd) {
+        ICLogger.d(cmd);
+        //(002C357593060153353AP21,7,0000000000000016)
+
+        String cmdlist[] = cmd.split(CMDSPLIT);
+        if (cmdlist.length == 3) {
+            String index = cmdlist[2];
+            try {
+                int mastervolume = Integer.parseInt(cmdlist[1]);
+
+                ICLogger.d("set volumn  " + mastervolume);
+                int volume = mastervolume * 2;
+                if (volume < 0) volume = 0;
+                if (volume >= 14) volume = 15;
+                Config.setMasterVolume(runtime.getContextProxy().context, mastervolume * 2);
+                ICAudioManager.setMasterVolumn(runtime.getContextProxy().context, mastervolume * 2);
+                connection.send(BPXX_REPLY(runtime, CMD_TYPE.BP21, index, true));
+            } catch (Exception e) {
+                ICLogger.e(e.getMessage(), e);
+                connection.send(BPXX_REPLY(runtime, CMD_TYPE.BP21, index, false));
+            }
+
+        } else {
+            ICLogger.e("AP21 format error");
+        }
+    }
+    public static StringMessage BP32(Runtime ds) {
+        //(001D0106357593060153353BP32,AP26)
+        //终端请求下发APP URL数据(AP26)
+        StringMessage ret = null;
+        StringBuilder sb = new StringBuilder(cmdMap.get(CMD_TYPE.BP32));
+        sb.append(CMDSPLIT).append(cmdMap.get(CMD_TYPE.AP26));
+        ret = genStringMessage(cmdMap.get(CMD_TYPE.BP32), AddHeader(ds, sb.toString()));
+        return ret;
+    }
+    public void handleAP34(Runtime runtime, Connection connection, String cmd) {
+        ICLogger.d(cmd);
+        //失败:
+        //(003D357593060153353AP34,13026618172,170413163300,2710,6,1,0)
+        //(003E357593060153353AP34,13026618172,170413163300,2710,6,1,-1)
+        //0:表示其它错误
+        //-1:表示13026618172不是手表的情亲号码
+        //成功:
+        //(003D357593060153353AP34,13026618172,170413163300,2710,6,1,1)
+
+        String cmdlist[] = cmd.split(CMDSPLIT);
+        if (cmdlist.length == 7) {
+            String index = cmdlist[2];
+
+            try {
+                String time = cmdlist[2];
+                String senderNum=cmdlist[1];
+                int packetCount = Integer.parseInt(cmdlist[4]);
+                int packetIndex = Integer.parseInt(cmdlist[5]);
+                int receiveSuccess = Integer.parseInt(cmdlist[6]);
+                ICLogger.i("服务器在" + time + " 收到 "+senderNum+" 的语音 " + packetIndex + "/" + packetCount + " " + (receiveSuccess == 1 ? "成功" : (receiveSuccess==0?"失敗":"非好友消息")));
+                if (receiveSuccess == 1) {
+                    //如果服务器接收 语音成功,则设置下一个要发送的语音包Index,当index == packetCount的时候表示所有包发送完毕,停止继续发送
+                    voicePacket.getInstanceSent().setCurrentIndexToSent(packetIndex);
+                    //发送消息,再次检查要发送的语音包,确认其发送完毕
+                    connection.DeliverCMDMessageToSystem("SentVoicePacket", "SentVoicePacket");
+                } else if (receiveSuccess == 0){
+                    //发送消息,再次检查要发送的语音包,确认其发送完毕
+                    connection.DeliverCMDMessageToSystem("SentVoicePacket", "SentVoicePacket");
+                }
+
+            } catch (Exception e) {
+                ICLogger.e(e.getMessage(), e);
+            }
+
+        } else {
+            ICLogger.e("AP34 format error");
+        }
+    }
+
+
+    public static byte[] BP34_Raw(String senderNumb,String packetTime, String recordtimelenHex, int count, int index, int datalen, byte[] amrdata) {
+//(03C80106357593060153353BP34,13026618172,170413163300,2710,6,1,700,数据)
+//BP34:命令字符
+//1:亲情号码 (0表示发给所有人)
+//170413163300:YYMMDDHHMMSS格式的年月日时分秒,设备录音时间
+//2710(0x2710):语音文件录音时长10000ms
+//6:语音包分包总数
+
+        Runtime runtime =(CoreService.getInstance()==null)?null:CoreService.getInstance().getRuntime();
+
+        /*
+        (    CHAR            1
+        %04X   HEX_STRING      4
+        0106   C_STRING        4
+           C_STRING            15
+           byte[]              msg.lenght
+           )  CHAR             1
+           */
+        if (runtime==null) return null;
+        StringBuffer sb = new StringBuffer(CMDHEADER).append("0000").append("0106").append(runtime.IMEI());
+                sb.append(cmdMap.get(CMD_TYPE.BP34))
+                .append(CMDSPLIT).append(senderNumb)
+                .append(CMDSPLIT).append(packetTime)
+                .append(CMDSPLIT).append(recordtimelenHex)
+                .append(CMDSPLIT).append(count)
+                .append(CMDSPLIT).append(index)
+                .append(CMDSPLIT).append(datalen)
+                .append(CMDSPLIT).toString();
+        int len=1 + 4 + 4 + 15 + sb.length() +datalen+ 1;
+        String lenstr = String.format("%04X",len);
+        byte[] sentbuf = new byte[len];
+        System.arraycopy(sb.toString().getBytes(), 0, sentbuf, 0, len-1-datalen);
+        System.arraycopy(amrdata, 0, sentbuf, sb.length(), datalen);
+        System.arraycopy(lenstr.getBytes(),0,sentbuf,1,4);
+        sentbuf[len-1] = ')';
+
+        return encrepteMsgBytes(sentbuf);
+
+    }
+
+    public void sendVoicePackage(int duration, String remoteNum, String content, String voiceId)  {
+
+        //创建voiceConent并添加到数据
+        final VoiceContent voiceContent = VoiceContent.placeHolderOut(CONTACT_CATEGORY_GROUP, remoteNum,String.format("%04X",duration), content, 1, 3);
+        // 把voiceContent拆解成1024的分包
+        Util.parseToVoicePacketSent(voiceContent,900);
+        //trigger 分包发送
+        if(CoreService.getInstance().getConnection() !=null)
+                CoreService.getInstance().getConnection().DeliverCMDMessageToSystem("SentVoicePacket","");
+
+    }
     public boolean handleCmd(CMD_TYPE type, String cmd) {
 
         //普通非二进制命令用此函数处理
@@ -1096,7 +1249,9 @@ SOS报警上行WIFI、LBS混合定位数据,步数为255步,电量等级5,数
             case AP11://服务器推送待接收消息
                 handleAP11(mRuntime,mConnection,cmd);
                 break;
-
+            case AP21://服务器推送音量设置消息
+                handleAP21(mRuntime,mConnection,cmd);
+                break;
 //            case AP14:// wifi定位包
 //                handleBP02(cmd);
 //                ICLogger.i("服务器收到定位AP02");