add shutdown cmd parse.
authorTrillGates <williamtrillgates@gmail.com>
Mon, 26 Apr 2021 06:56:58 +0000 (14:56 +0800)
committerTrillGates <williamtrillgates@gmail.com>
Mon, 26 Apr 2021 06:56:58 +0000 (14:56 +0800)
app/release/ICSer_V779_2104251624_release.apk [moved from app/release/ICSer_V778_2104230944_release.apk with 78% similarity]
app/release/output.json
app/src/main/java/com/ic/protocols/protocolAPIHelper.java
app/src/main/java/com/ic/protocols/protocol_anan.java
app/version_code.properties

similarity index 78%
rename from app/release/ICSer_V778_2104230944_release.apk
rename to app/release/ICSer_V779_2104251624_release.apk
index 58ee0be..35619b1 100644 (file)
Binary files a/app/release/ICSer_V778_2104230944_release.apk and b/app/release/ICSer_V779_2104251624_release.apk differ
index 56f16de..0b31224 100644 (file)
@@ -1 +1 @@
-[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":778,"versionName":"2104230944","enabled":true,"outputFile":"ICSer_V778_2104230944_release.apk","fullName":"release","baseName":"release"},"path":"ICSer_V778_2104230944_release.apk","properties":{}}]
\ No newline at end of file
+[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":779,"versionName":"2104251624","enabled":true,"outputFile":"ICSer_V779_2104251624_release.apk","fullName":"release","baseName":"release"},"path":"ICSer_V779_2104251624_release.apk","properties":{}}]
\ No newline at end of file
index 63c1824..a28b315 100644 (file)
@@ -83,7 +83,7 @@ public class protocolAPIHelper {
                 protocolmqtt_handler.parserCmd(cmd_type, bytes);
                 break;
             case PROTOCOL_ANAN:
-                protocolanan_handler.parseCmd(cmd_type, bytes);
+                protocolanan_handler.parseCmd(bytes);
                 break;
 
         }
index bef5663..ccab10a 100644 (file)
@@ -5,17 +5,26 @@ import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.Environment;
 import android.telephony.TelephonyManager;
 
+import com.enqualcomm.support.Config;
+import com.enqualcomm.support.bean.Content;
 import com.enqualcomm.support.bean.Runtime;
 import com.enqualcomm.support.bean.StringMessage;
+import com.enqualcomm.support.bean.VoiceContent;
+import com.enqualcomm.support.bean.voicePacket;
 import com.enqualcomm.support.utils.Connection;
 import com.enqualcomm.support.utils.ICLogger;
 import com.enqualcomm.support.utils.TimeUtil;
+import com.enqualcomm.support.utils.Util;
 
+import java.io.File;
 import java.util.HashMap;
 import java.util.Locale;
 
+import static com.enqualcomm.support.bean.Contact.GROUP_ALL;
 import static java.lang.Math.abs;
 
 /**
@@ -157,6 +166,12 @@ public class protocol_anan {
         BPFD/*交好友响应*/,
         BP07/*语音上行响应*/,
         BP95/*语音上行给好友响应*/,
+        BP28/*语音下行*/,
+        AP28/*语音反馈*/,
+        AP16/*立即定位*/,
+        AP17/*恢复出厂设置*/,
+        AP18/*重启上行*/,
+        AP31/*关机上行*/
     }
 
 
@@ -177,6 +192,7 @@ public class protocol_anan {
         cmdMap.put(CMD_TYPE.APFD, "APFD");
         /* 服务器发起*/
         cmdMap.put(CMD_TYPE.BP12, "BP12");
+        cmdMap.put(CMD_TYPE.AP16, "AP16");
         cmdMap.put(CMD_TYPE.BP14, "BP14");
         cmdMap.put(CMD_TYPE.BP07, "BP07");
         cmdMap.put(CMD_TYPE.BP44, "BP44");
@@ -201,6 +217,10 @@ public class protocol_anan {
         cmdMap.put(CMD_TYPE.BP99, "BP99");
         cmdMap.put(CMD_TYPE.BPSW, "BPSW");
         cmdMap.put(CMD_TYPE.BP95, "BP95");
+        cmdMap.put(CMD_TYPE.BP28, "BP28");
+        cmdMap.put(CMD_TYPE.AP28, "AP28");
+        cmdMap.put(CMD_TYPE.AP17, "AP17");
+        cmdMap.put(CMD_TYPE.AP18, "AP18");
 
     }
 
@@ -216,19 +236,19 @@ public class protocol_anan {
     }
 
     public static byte[] AP07(String packetTime, int count, int index, int datalen, byte[] amrdata) {
-//IWAP07,20140818064408,6,1,1024,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#
-//说明:
-//IW:标识符
-//AP07 : 命令字符
-//20140818064408 :yyyyMMddHHmmss 格式的年月日时分秒,设备录音时间
-//6:语音包分包总数
-//1 :当前包数,第一包为1,第二包为2,。。。。。。同一个语音包的语音时间相同
-//1024 :语音包长度
-//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:当前音频数据, 每个音频数据包大小为1024字节,最后一包不足1024的取实际字节数
-//语音包上传规则:
-//按包次序依次上传,上传后如果没有收到服务器的响应包,则继续上传该语音包。
-//收到设备回复确认数据包接收成功状态后,继续开始依次上传下一个数据包。。。。。。
-//如果设备回复确认数据包接收失败状态,则重复发送上一个数据包
+        //IWAP07,20140818064408,6,1,1024,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#
+        //说明:
+        //IW:标识符
+        //AP07 : 命令字符
+        //20140818064408 :yyyyMMddHHmmss 格式的年月日时分秒,设备录音时间
+        //6:语音包分包总数
+        //1 :当前包数,第一包为1,第二包为2,。。。。。。同一个语音包的语音时间相同
+        //1024 :语音包长度
+        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:当前音频数据, 每个音频数据包大小为1024字节,最后一包不足1024的取实际字节数
+        //语音包上传规则:
+        //按包次序依次上传,上传后如果没有收到服务器的响应包,则继续上传该语音包。
+        //收到设备回复确认数据包接收成功状态后,继续开始依次上传下一个数据包。。。。。。
+        //如果设备回复确认数据包接收失败状态,则重复发送上一个数据包
 
 
         String sb = new StringBuffer(CMDHEADER).append(cmdMap.get(CMD_TYPE.AP07))
@@ -435,10 +455,337 @@ public class protocol_anan {
         return sm;
     }
 
+    private int dataPart = 1;
+
+    private static final String CMD_HEADER = "[";
+    private static final String CMD_COMPANY = "IC";
+    private static final String CMD_END = "]";
+    private static final String CMD_HEADER_SPLIT = "*";
+    private static final String CMD_SPLIT = ",";
+    private byte[] totalByte;
+
+    private StringBuffer cmdbuf = new StringBuffer();
 
     //指令解析
-    public void parseCmd(String cmd_type, byte[] bytes) {
-        ICLogger.d("cmd_type == > " + cmd_type);
-        ICLogger.d("byte == > " + new String(bytes));
+    public void parseCmd(byte[] bytes) {
+        boolean iscmdComplete = false;
+        boolean ret = true;
+        String last_inCompletecmd = "";
+        String cmd_msgbuf = new String(bytes);
+        ICLogger.d("bytes.size " + bytes.length);
+//        cmdbuf.append(cmd_msgbuf);
+        cmdbuf.append(cmd_msgbuf);
+        ICLogger.d("cmdbuf.size " + cmdbuf.length() + " " + cmdbuf.toString());
+    /*
+        如果不是 #结尾,就认为 接收数据不全,置位。
+         */
+        if (cmdbuf.toString().endsWith(CMDEND)) {
+            iscmdComplete = true;
+        }
+        String[] cmdlist = cmd_msgbuf.split(CMDEND);
+        int listLen = cmdlist.length;
+        ICLogger.d("listLen " + listLen);
+         /*
+        如果解析出来的cmdlist不是空,且数据不是完整cmd则保留 最后一条数据到last_inCompletecmd
+         */
+        if (cmdlist.length > 0 && !iscmdComplete) {
+            listLen -= 1;
+            last_inCompletecmd = cmdlist[listLen];
+            ICLogger.d("cmd not complete , " + last_inCompletecmd);
+        }
+        for (int i = 0; i < listLen; i++) {
+            for (CMD_TYPE key : cmdMap.keySet()) {
+                if (cmdlist[i].startsWith(CMDHEADER + cmdMap.get(key))) {
+                    ICLogger.d("found cmd keyid=" + key +
+                            " ,keyname=" + cmdMap.get(key)
+                            + " ,  " + cmdlist[i]);
+                    if (key == CMD_TYPE.BP28) {
+                        //如果是BP28则 后面的数据是音频,需要保留
+                        int amrLen = getBP28Amrlen(cmdlist[i]);
+                        if (bytes.length > amrLen) {
+                            handleCmd(key, cmdlist[i], bytes);
+                        }
+                    } else {
+                        handleCmd(key, cmdlist[i]);
+                    }
+                }
+            }
+        }
+
+        cmdbuf = new StringBuffer().append(last_inCompletecmd);
+    }
+
+    public void handleCmd(CMD_TYPE type, String cmd) {
+        //普通非二进制命令用此函数处理
+        boolean ret = true;
+        ICLogger.i("handleCmd " + type.name() + " strLen=" + cmd.length());
+        if (Config.LOG_TOFILE) ICLogger.logToFile("APILog", " recv " + cmd);
+        switch (type) {
+            case BP16:
+                //立即定位指令(长链接有效)
+                handleBP16(mConnection, mRuntime, cmd);
+                mConnection.DeliverCMDMessageToSystem("StartLocate", cmd);//通知下面线程状态变化
+                break;
+            case BP17:
+                //收到恢复出厂设置
+                handleBP17(mConnection, cmd);
+                ICLogger.i("收到服务器恢复出厂设置命令BP17");
+                mConnection.DeliverCMDMessageToSystem("FactoryReset", cmd);//通知下面线程状态变化
+                break;
+            case BP18:
+                //收到重启
+                handleBP18(mConnection, cmd);
+                ICLogger.i("收到服务器重启命令BP18");
+                mConnection.DeliverCMDMessageToSystem("Reboot", cmd);//通知下面线程状态变化
+                break;
+            case BP31:
+                //收到关机
+                handleBP31(mConnection, cmd);
+                ICLogger.i("收到服务器关机命令BP31");
+                mConnection.DeliverCMDMessageToSystem("poweroff", cmd);//通知下面线程状态变化
+                break;
+        }
+    }
+
+
+    public void handleBP31(Connection connection, String cmd) {
+
+        //    IWBP31,867155030001063,161723
+        String[] cmdlist = cmd.split(CMDSPLIT);
+        if (cmdlist.length == 3) {
+
+            connection.send(AP31(cmdlist[2]));
+
+        }
     }
+
+
+    public static StringMessage AP31(String index) {
+        return genStringMessage(cmdMap.get(CMD_TYPE.AP31),
+                new StringBuffer(CMDHEADER).append(cmdMap.get(CMD_TYPE.AP31))
+                        .append(CMDSPLIT).append(index)
+                        .append(CMDEND).toString());
+    }
+
+    public void handleBP18(Connection connection, String cmd) {
+
+        //    IWBP18,867155030001063,161723
+        String[] cmdlist = cmd.split(CMDSPLIT);
+        if (cmdlist.length == 3) {
+
+            connection.send(AP18(cmdlist[2]));
+
+        }
+    }
+
+
+    public static StringMessage AP18(String index) {
+        return genStringMessage("AP18", new StringBuffer(CMDHEADER).append(cmdMap.get(CMD_TYPE.AP18))
+                .append(CMDSPLIT).append(index)
+                .append(CMDEND).toString());
+    }
+
+    public void handleBP17(Connection connection, String cmd) {
+
+        //IWBP17,867155030001063,161723
+        String[] cmdlist = cmd.split(CMDSPLIT);
+        if (cmdlist.length == 3) {
+            connection.send(AP17(cmdlist[2]));
+        }
+    }
+
+    //恢复出厂设置
+    public static StringMessage AP17(String index) {
+        return genStringMessage("AP17",
+                new StringBuffer(CMDHEADER).append(cmdMap.get(CMD_TYPE.AP17))
+                        .append(CMDSPLIT).append(index)
+                        .append(CMDEND).toString());
+    }
+
+    //    立即定位指令(长链接有效)
+    public void handleBP16(Connection connection, Runtime runtime, String cmd) {
+        //示例数据:IWBP16,867155030001063,335386
+//        IWBP16,353456789012345,080835#
+//        说明:
+//        IW:标识符
+//        BP16 : 命令字符
+//        353456789012345:IMEI号,设备唯一ID
+//        080835 :指令流水号
+        String[] cmdlist = cmd.split(",");
+        if (cmdlist.length == 3) {
+            ICLogger.d("imei " + cmdlist[1] + ", cmdindex " + cmdlist[2]);
+
+            connection.send(AP16(cmdlist[2]));
+        } else {
+            ICLogger.d("error BP16 format");
+        }
+    }
+
+    //立即定位反馈
+    public static StringMessage AP16(String cmdindex) {
+        //IWAP16,080835#
+        //080835:指令流水号
+        return genStringMessage("AP16",
+                new StringBuffer(CMDHEADER).append(cmdMap.get(CMD_TYPE.AP16))
+                        .append(CMDSPLIT).append(cmdindex)
+                        .append(CMDEND).toString());
+    }
+
+    public boolean handleCmd(CMD_TYPE type, String cmd, byte[] bytes) {
+
+        //只有需要传递二级制数据的才需要这个函数,目前只有BP28需要
+
+        boolean ret = true;
+        ICLogger.i("handleCmd " + type.name() + " " + cmd + " bytelen=" + bytes.length);
+        if (Config.LOG_TOFILE) ICLogger.logToFile("APILog", " recv " + new String(bytes));
+        switch (type) {
+            case BP28:
+                handleBP28(mConnection, cmd, mRuntime, bytes);
+                ICLogger.i("收到服务器语音BP28");
+                mConnection.DeliverCMDMessageToSystem("BP28", "");//通知下面线程状态变化
+                break;
+        }
+        return ret;
+    }
+
+
+    //处理 BP28 语音消息
+    public void handleBP28(Connection connection, String cmd, Runtime runtime, byte[] bytes) {
+        //log("handleBP28 msg"+cmd);
+        /**
+         * IWBP28, D3590D54,XXXX,6,1,1024,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#
+         * 说明:
+         * IW:标识符
+         * BP28 : 命令字符
+         * D3590D54:UNICODE编码,发送者名称
+         * XXXX: 附加信息,在响应数据包时,将附加信息原样响应,类似流水号
+         * 6:语音包分包总数
+         * 1 :当前包数,第一包为1,第二包为2,。。。。。。同一个语音包的语音时间相同
+         * 1024 :语音包长度
+         * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:当前音频数据, 每个音频数据包大小为1024字节,最后一包不足1024的取实际字节数
+         * 语音包上传规则:
+         * 按包次序依次上传,上传后如果没有收到服务器的响应包,则继续上传该语音包。
+         * 收到设备回复确认数据包接收成功状态后,继续开始依次上传下一个数据包。。。。。。
+         * 如果设备回复确认数据包接收失败状态,则重复发送上一个数据包
+         * 设备响应:     IWAP28,D3590D54,XXXX,6,1,1#
+         * D3590D54:UNICODE编码,发送者名称
+         * XXXX: 附加信息,原样返回
+         * 6:语音包分包总数
+         * 1:当前设备收到的是第几个包
+         * 1:表示设备接受数据成功,0表示设备接受数据失败
+         */
+        String Name;
+        String appendIndex;
+        int packetCount;
+        int currentId;
+        int packetLen;
+        byte[] packetData;
+
+        String[] msg = cmd.split(CMDSPLIT);
+        if (msg.length >= 6) {
+            try {
+                Name = msg[1];
+                appendIndex = msg[2];
+                packetCount = Integer.parseInt(msg[3]);
+                currentId = Integer.parseInt(msg[4]);
+                packetLen = Integer.parseInt(msg[5]);
+                packetData = Util.subArray(bytes,
+                        msg[0].length() + msg[1].length() + msg[2].length() + msg[3].length() + msg[4].length() + msg[5].length() + 6, bytes.length - 1);
+
+                StringBuffer stringBuffer = new StringBuffer();
+                stringBuffer.append("recv BP28 name = ").append(Name)
+                        .append(",appendIndex = ").append(appendIndex)
+                        .append(",packetCount = ").append(packetCount)
+                        .append(",currentId = ").append(currentId)
+                        .append(",packetLen = ").append(packetLen)
+                        .append(",packetDatalen = ").append(packetData.length);
+
+                ICLogger.d(stringBuffer.toString());
+                connection.send(AP28(Name, appendIndex, packetCount, currentId, 1));
+                voicePacket.getInstance().appendVoice(Name,
+                        appendIndex, packetCount, currentId, packetLen, packetData);
+                ICLogger.d("================" + voicePacket.getInstance().toString());
+                if (voicePacket.getInstance().isFinished()) {
+
+                    String dir = Environment.getExternalStorageDirectory() + "/Android/VoiceCache";
+                    String amrFilepath = Util.saveFile(voicePacket.getInstance().getVoicePacketBytes(), 0, voicePacket.getInstance().getVoicePacketLen(), new File(dir), "receive_" + voicePacket.getInstance().getPacketTime() + ".amr");
+                    ICLogger.i("save Amr file to " + amrFilepath);
+                    voicePacket.getInstance().clearPacket();
+                    VoiceContent voiceContent = VoiceContent.placeHolderIn(Content.CONTACT_CATEGORY_GROUP, GROUP_ALL, amrFilepath);
+
+
+                    final Uri uri2 = runtime.getDbHelper().insertMessage(voiceContent);
+
+                    //回复UI消息,表示已经接收到
+                    voiceContent.status = 3;
+                    voiceContent.serverTime = TimeUtil.getSystemTime3();
+                    voiceContent.preview = String.valueOf(Util.getDuration(voiceContent.content));
+                    runtime.getDbHelper().updateMessage(voiceContent, uri2);
+
+//                runtime.getContextProxy().sendBroadcast(ACTION_IMESSAGE, runtime);
+
+                    connection.DeliverCMDMessageToSystem("NewVoice", amrFilepath);//通知下面线程状态变化
+                }
+            } catch (Exception e) {
+                ICLogger.e(e.getMessage(), e);
+            }
+        } else {
+            ICLogger.d("handleBP28 format Error");
+//            connection.send(genStringMessage("AP28",AP28(Name,appendIndex,packetCount,currentId,0)));
+
+        }
+
+    }
+
+    /*语音下行反馈*/
+    public static StringMessage AP28(String name, String msg, int packagecount, int currentpackageindex, int received_success) {
+        //示例数据:IWAP28,D3590D54,xxxx,6,1,1#
+        return genStringMessage("AP28", new StringBuffer(CMDHEADER).append(cmdMap.get(CMD_TYPE.AP28))
+                .append(CMDSPLIT).append(name)
+                .append(CMDSPLIT).append(msg)
+                .append(CMDSPLIT).append(packagecount)
+                .append(CMDSPLIT).append(currentpackageindex)
+                .append(CMDSPLIT).append(received_success)
+                .append(CMDEND).toString());
+    }
+
+
+    public int getBP28Amrlen(String cmd) {
+
+        String Name;
+        String appendIndex;
+        int packetCount;
+        int currentId;
+        int packetLen;
+
+
+        String[] msg = cmd.split(CMDSPLIT);
+        if (msg.length >= 6) {
+
+            try {
+                Name = msg[1];
+                appendIndex = msg[2];
+                packetCount = Integer.parseInt(msg[3]);
+                currentId = Integer.parseInt(msg[4]);
+                packetLen = Integer.parseInt(msg[5]);
+
+                StringBuffer stringBuffer = new StringBuffer();
+                stringBuffer.append("getBP28AmrLen name = ").append(Name)
+                        .append(",appendIndex = ").append(appendIndex)
+                        .append(",packetCount = ").append(packetCount)
+                        .append(",currentId = ").append(currentId)
+                        .append(",packetLen = ").append(packetLen);
+
+                ICLogger.d(stringBuffer.toString());
+                return packetLen;
+            } catch (Exception e) {
+                ICLogger.e(e.getMessage(), e);
+            }
+        } else {
+            ICLogger.d("getBP28AmrLen format Error");
+
+        }
+        return -1;
+    }
+
 }
index a1401fb..66e01c0 100644 (file)
@@ -1,2 +1,2 @@
-#Fri Apr 23 09:44:07 CST 2021
-VERSION_CODE=778
+#Sun Apr 25 16:24:46 CST 2021
+VERSION_CODE=779