whyclj
2019-10-16 3825e10fc9eba23411e8836b34ba70ed10abee7b
添加后台
17个文件已添加
5个文件已修改
2463 ■■■■■ 已修改文件
package.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/CordovaLib/cordova.gradle 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/android.iml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/app.iml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/build.gradle 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/gradle/wrapper/gradle-wrapper.jar 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/gradle/wrapper/gradle-wrapper.properties 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/gradlew 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/gradlew.bat 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/libs/commons-net-3.6.jar 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/src/main/java/com/mode/BattRTData.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/src/main/java/com/mode/BattTestParam.java 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/src/main/java/com/mode/BattTestRtData.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/src/main/java/com/mode/ServiceModel.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/src/main/java/com/socket/MySocketClientThread.java 435 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/src/main/java/com/util/Com.java 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/src/main/java/com/util/ComFn.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/src/main/java/com/util/Ecb_Aes.java 570 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/src/main/java/com/util/FBS_Cmd.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/src/main/java/com/util/FBS_ComBase.java 307 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/src/main/java/com/util/FBS_ComBuf.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platforms/android/app/src/main/java/com/util/FBS_Crc16.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json
@@ -29,4 +29,4 @@
      "android"
    ]
  }
}
}
platforms/android/CordovaLib/cordova.gradle
@@ -29,9 +29,9 @@
String doGetProjectTarget() {
    def props = new Properties()
    def propertiesFile = 'project.properties';
    def propertiesFile = 'project.properties'
    if(!(file(propertiesFile).exists())) {
      propertiesFile = '../project.properties';
      propertiesFile = '../project.properties'
    }
    file(propertiesFile).withReader { reader ->
        props.load(reader)
@@ -149,8 +149,8 @@
                    label(text: msg)
                    def input = passwordField()
                    button(defaultButton: true, text: 'OK', actionPerformed: {
                        ret = input.password;
                        dispose();
                        ret = input.password
                        dispose()
                    })
                }
            }
@@ -160,7 +160,7 @@
        }
        return new String(ret)
    } else {
        return System.console().readPassword('\n' + msg);
        return System.console().readPassword('\n' + msg)
    }
}
platforms/android/android.iml
@@ -13,7 +13,7 @@
    <content url="file://$MODULE_DIR$">
      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
    </content>
    <orderEntry type="inheritedJdk" />
    <orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
    <orderEntry type="sourceFolder" forTests="false" />
  </component>
</module>
platforms/android/app/app.iml
@@ -89,8 +89,8 @@
    </content>
    <orderEntry type="jdk" jdkName="Android API 28 Platform" jdkType="Android SDK" />
    <orderEntry type="sourceFolder" forTests="false" />
    <orderEntry type="module" module-name="CordovaLib" />
    <orderEntry type="module" module-name="CordovaLib" />
    <orderEntry type="library" name="Gradle: __local_aars__:D.\GitVisualStudioWorkSpace\hybirdApp\platforms\android\app\libs\commons-net-3.6.jar:unspecified@jar" level="project" />
    <orderEntry type="library" name="Gradle: com.google.code.gson:gson:2.8.5@jar" level="project" />
    <orderEntry type="module" module-name="CordovaLib" />
  </component>
</module>
platforms/android/app/build.gradle
@@ -50,11 +50,11 @@
    // The value for android.compileSdkVersion.
    if (!project.hasProperty('cdvCompileSdkVersion')) {
        cdvCompileSdkVersion = null;
        cdvCompileSdkVersion = null
    }
    // The value for android.buildToolsVersion.
    if (!project.hasProperty('cdvBuildToolsVersion')) {
        cdvBuildToolsVersion = null;
        cdvBuildToolsVersion = null
    }
    // Sets the versionCode to the given value.
    if (!project.hasProperty('cdvVersionCode')) {
@@ -70,7 +70,7 @@
    }
    // The value for android.targetSdkVersion.
    if (!project.hasProperty('cdvTargetSdkVersion')) {
        cdvTargetSdkVersion = null;
        cdvTargetSdkVersion = null
    }
    // Whether to build architecture-specific APKs.
    if (!project.hasProperty('cdvBuildMultipleApks')) {
@@ -115,7 +115,7 @@
    defaultCompileSdkVersion == null 
        ? privateHelpers.getProjectTarget()
        : defaultCompileSdkVersion 
) : Integer.parseInt('' + cdvCompileSdkVersion);
) : Integer.parseInt('' + cdvCompileSdkVersion)
if (ext.cdvBuildToolsVersion == null) {
    ext.cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
@@ -129,8 +129,8 @@
}
// Cast to appropriate types.
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean();
ext.cdvVersionCodeForceAbiDigit = cdvVersionCodeForceAbiDigit == null ? false : cdvVersionCodeForceAbiDigit.toBoolean();
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean()
ext.cdvVersionCodeForceAbiDigit = cdvVersionCodeForceAbiDigit == null ? false : cdvVersionCodeForceAbiDigit.toBoolean()
// minSdkVersion, maxSdkVersion and targetSdkVersion
ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? defaultMinSdkVersion : Integer.parseInt('' + cdvMinSdkVersion)
@@ -145,7 +145,7 @@
    def ret = 'assemble'
    if (cdvBuildMultipleApks && cdvBuildArch) {
        def arch = cdvBuildArch == 'arm' ? 'armv7' : cdvBuildArch
        ret += '' + arch.toUpperCase().charAt(0) + arch.substring(1);
        ret += '' + arch.toUpperCase().charAt(0) + arch.substring(1)
    }
    return ret + (debugBuild ? 'Debug' : 'Release')
}
@@ -200,7 +200,7 @@
    }
    lintOptions {
      abortOnError false;
      abortOnError false
    }
    compileSdkVersion cdvCompileSdkVersion
@@ -294,17 +294,21 @@
    // SUB-PROJECT DEPENDENCIES START
    implementation(project(path: ":CordovaLib"))
    // SUB-PROJECT DEPENDENCIES END
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation files('libs/commons-net-3.6.jar')
}
def promptForReleaseKeyPassword() {
    if (!cdvReleaseSigningPropertiesFile) {
        return;
        return
    }
    if ('__unset'.equals(android.signingConfigs.release.storePassword)) {
        android.signingConfigs.release.storePassword = privateHelpers.promptForPassword('Enter key store password: ')
    }
    if ('__unset'.equals(android.signingConfigs.release.keyPassword)) {
        android.signingConfigs.release.keyPassword = privateHelpers.promptForPassword('Enter key password: ');
        android.signingConfigs.release.keyPassword = privateHelpers.promptForPassword('Enter key password: ')
    }
}
@@ -336,7 +340,7 @@
    signingConfig.storePassword = props.get('storePassword', props.get('key.store.password', signingConfig.storePassword))
    def storeType = props.get('storeType', props.get('key.store.type', ''))
    if (!storeType) {
        def filename = storeFile.getName().toLowerCase();
        def filename = storeFile.getName().toLowerCase()
        if (filename.endsWith('.p12') || filename.endsWith('.pfx')) {
            storeType = 'pkcs12'
        } else {
platforms/android/app/gradle/wrapper/gradle-wrapper.jar
Binary files differ
platforms/android/app/gradle/wrapper/gradle-wrapper.properties
New file
@@ -0,0 +1,6 @@
#Tue Oct 15 18:14:31 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
platforms/android/app/gradlew
New file
@@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
    echo "$*"
}
die () {
    echo
    echo "$*"
    echo
    exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
  NONSTOP* )
    nonstop=true
    ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
    JAVACMD=`cygpath --unix "$JAVACMD"`
    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi
# Escape application args
save () {
    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
    echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
  cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
platforms/android/app/gradlew.bat
New file
@@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
platforms/android/app/libs/commons-net-3.6.jar
Binary files differ
platforms/android/app/src/main/java/com/mode/BattRTData.java
New file
@@ -0,0 +1,99 @@
package com.mode;
import java.nio.ByteBuffer;
import java.util.Arrays;
import com.util.ComFn;
import com.util.*;
public class BattRTData {
    private final int BATTGROUP_COUNT = FBS_ComBase.BattGroupCountMax;        //电池组的组数
    private final int BYTE_HEAD_LEN = 32;                                    //头部长度为32个字节
    public int monsum;
    public double[] groupvol = new double[BATTGROUP_COUNT];                    //组端电压
    public double[] groupcur = new double[BATTGROUP_COUNT];                    //组端电流
    public int[]     battstate = new int[BATTGROUP_COUNT];                    //电池状态
    public double vol[] = new double[FBS_ComBase.MonomerCountMax];            //单体电压
    public boolean putByteBuffer(ByteBuffer bf,int BYTECOUNT) {
        monsum = (BYTECOUNT - 32)/2;
        if(monsum <= 0) {
            return false;
        }
        if(monsum > 480) {
            monsum = 480;
        }
        ByteBuffer tmpbuf = bf;
        tmpbuf.position(0);
        for(int i=0;i<BATTGROUP_COUNT;i++) {
            groupvol[i] = FBS_ComBase.changeShortToDouble(tmpbuf.getShort())/10;
        }
        for(int i=0;i<BATTGROUP_COUNT;i++) {
            groupcur[i] = FBS_ComBase.changeShortToDouble(tmpbuf.getShort())/10;
        }
        for(int i=0;i<BATTGROUP_COUNT;i++) {
            battstate[i] = FBS_ComBase.changeShortToInt(tmpbuf.getShort());
        }
        for(int i=0;i<monsum;i++) {
            vol[i] = FBS_ComBase.changeShortToDouble(tmpbuf.getShort())/1000;
        }
        System.out.println(this);
        return true;
    }
    public double[] getGroupvol() {
        return groupvol;
    }
    public double[] getGroupcur() {
        return groupcur;
    }
    public int[] getBattstate() {
        return battstate;
    }
    public double[] getVol() {
        return vol;
    }
    public void setGroupvol(double[] groupvol) {
        this.groupvol = groupvol;
    }
    public void setGroupcur(double[] groupcur) {
        this.groupcur = groupcur;
    }
    public void setBattstate(int[] battstate) {
        this.battstate = battstate;
    }
    public void setVol(double[] vol) {
        this.vol = vol;
    }
    public int getMonsum() {
        return monsum;
    }
    public void setMonsum(int monsum) {
        this.monsum = monsum;
    }
    @Override
    public String toString() {
        return "BattData [monsum=" + monsum + ", groupvol=" + Arrays.toString(groupvol) + ", groupcur="
                + Arrays.toString(groupcur) + ", battstate=" + Arrays.toString(battstate) + ", vol="
                + Arrays.toString(vol) + "]";
    }
}
platforms/android/app/src/main/java/com/mode/BattTestParam.java
New file
@@ -0,0 +1,168 @@
package com.mode;
import com.util.FBS_ComBase;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
public class BattTestParam {
    private final int BYTE_LEN = 52;
    public String battName = "";        //电池组名称
    public byte[] byteName;                //电池组名称字节数组
    public int param_index;                //预置索引号
    //public int testMode;                //测试模式    0:离线        1:在线
    //public int powerOffAction;        //市电中断处理   0:继续放电    1:停止放电
    public int battStdCap;                //电池组标称容量
    public int hourState;                //放电小时率    1、2、3、4、5、6、7、8、9、10、20
    public double disChargeCurr;        //放电电流(0.1A)
    public int disChargeCap;            //放电容量(1AH)
    public int disTime;                    //放电时长(min)
    public double monVolLow;            //单体下限(0.01V)
    public double groupVolLow;            //组端下限(0.1V)
    public int monCount;                //每组单体数(每组电池节数)0~240
    public int groupCount;                //电池组组数(1~4)
    public int monVolLowCount;            //单体下限数量(0~240)
    //public int saveInterval;            //数据保存间隔min
    public double dcVolHighLimit;        //升压上限(0.1V)
    //public double chargeCurr;            //充电电压(在线阈值)A
    public int testType;                //测试类型(0:恒电流    1:恒功率      2:恒电阻)
    public double dischargePower;        //预放功率(0.1kw)
    public double chargeCurr;            //充电电流(0.1A)
    public double chargeVol;            //充电电压(0.1V)
    public double floatVol;                //浮充电压(0.1V)
    //public double chargeCap;            //充电容量
    public int chargeTime;                //充电时长(min)
    public int floatTime;                //浮充时长(min)
    public double chargeStopCurr;        //截止电流(0.1A)
    public double groupHighVol;            //组端上限(0.1V)
    public double monHighVol;            //单体上限(0.01V)
    public int monHighVolCount;            //单体上限数量
    //public double chargeHighTmp;        //充电过温
    //public double dischargeHighTmp;    //放电过温
    public int cycleStart;                //活化起点     0放电 ,1充电
    public int cycleTimes;                //活化次数     1-50次
    public int waitdisTime;                //充完静置    0-500分钟
    public int waitchrTime;                //放完静置    0-500分钟
    public boolean putByteBuffer(ByteBuffer bf) {
        if(bf.limit()<BYTE_LEN) {
            return false;
        }
        ByteBuffer tmpbuf = bf;
        tmpbuf.position(0);
        battStdCap = FBS_ComBase.changeShortToInt(bf.getShort());                //标称容量
        hourState  = FBS_ComBase.changeShortToInt(bf.getShort());                //小时率
        disChargeCurr = FBS_ComBase.changeShortToDouble(bf.getShort())/10;        //放电电流
        disChargeCap = FBS_ComBase.changeShortToInt(bf.getShort());                //放电容量
        disTime = FBS_ComBase.changeShortToInt(bf.getShort());                    //放电时长
        monVolLow = FBS_ComBase.changeShortToDouble(bf.getShort())/100;            //单体下限阀值
        groupVolLow = FBS_ComBase.changeShortToDouble(bf.getShort())/10;        //组端下限
        monCount = FBS_ComBase.changeShortToInt(bf.getShort());                    //每组单体数量
        groupCount = FBS_ComBase.changeShortToInt(bf.getShort());                //电池组组数
        monVolLowCount = FBS_ComBase.changeShortToInt(bf.getShort());            //单体下限数量
        dcVolHighLimit = FBS_ComBase.changeShortToDouble(bf.getShort())/10;        //升压上限
        testType = FBS_ComBase.changeShortToInt(bf.getShort());                    //测试类型
        dischargePower = FBS_ComBase.changeShortToDouble(bf.getShort())/10;        //预放功率
        chargeCurr = FBS_ComBase.changeShortToDouble(bf.getShort())/10;            //充电电流
        chargeVol = FBS_ComBase.changeShortToDouble(bf.getShort())/10;            //充电电压
        floatVol = FBS_ComBase.changeShortToDouble(bf.getShort())/10;            //浮充电压
        chargeTime = FBS_ComBase.changeShortToInt(bf.getShort());                //充电时长
        floatTime = FBS_ComBase.changeShortToInt(bf.getShort());                //浮充时长
        chargeStopCurr = FBS_ComBase.changeShortToDouble(bf.getShort())/10;        //截止电流
        groupHighVol = FBS_ComBase.changeShortToDouble(bf.getShort())/10;        //组端上限
        monHighVol = FBS_ComBase.changeShortToDouble(bf.getShort())/100;        //单体上限
        monHighVolCount = FBS_ComBase.changeShortToInt(bf.getShort());            //单体上限数量
        cycleStart = FBS_ComBase.changeShortToInt(bf.getShort());                //活化起点
        cycleTimes = FBS_ComBase.changeShortToInt(bf.getShort());                //活化次数
        waitdisTime = FBS_ComBase.changeShortToInt(bf.getShort());                //充完静置
        waitchrTime = FBS_ComBase.changeShortToInt(bf.getShort());                //放完静置
        return true;
    }
    /**
     * 获取新建电池组的数据
     * @return
     */
    public ByteBuffer getNewBattByteBuffer() {
        byte[] b = null;
        try {
            b = battName.getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        int byteCount = b.length<20?b.length:20;
        ByteBuffer tmpbuf = ByteBuffer.allocate(byteCount);
        tmpbuf.order(ByteOrder.LITTLE_ENDIAN);
        tmpbuf.position(0);
        for(int i = 0;i<b.length && i<20;i++) {
            tmpbuf.put(FBS_ComBase.changeIntToByte(b[i]));
        }
        //System.out.println(ComFn.bytesToHexString(b, b.length));;
        return tmpbuf;
    }
    public ByteBuffer getByteBuffer() {
        ByteBuffer tmpbuf = ByteBuffer.allocate(BYTE_LEN);
        tmpbuf.order(ByteOrder.LITTLE_ENDIAN);
        tmpbuf.position(0);
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(battStdCap));                //标称容量
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(hourState));                //小时率
        tmpbuf.putShort(FBS_ComBase.changeDoubleToShort(disChargeCurr*10));        //放电电流
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(disChargeCap));            //放电容量
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(disTime));                    //放电时长
        tmpbuf.putShort(FBS_ComBase.changeDoubleToShort(monVolLow*100));        //单体下限阀值
        tmpbuf.putShort(FBS_ComBase.changeDoubleToShort(groupVolLow*10));        //组端下限
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(monCount));                //每组单体数量
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(groupCount));                //电池组组数
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(monVolLowCount));            //单体下限数量
        tmpbuf.putShort(FBS_ComBase.changeDoubleToShort(dcVolHighLimit*10));    //升压上限
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(testType));                //测试类型
        tmpbuf.putShort(FBS_ComBase.changeDoubleToShort(dischargePower*10));    //预放功率
        tmpbuf.putShort(FBS_ComBase.changeDoubleToShort(chargeCurr*10));        //充电电流
        tmpbuf.putShort(FBS_ComBase.changeDoubleToShort(chargeVol*10));            //充电电压
        tmpbuf.putShort(FBS_ComBase.changeDoubleToShort(floatVol*10));            //浮充电压
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(chargeTime));                //充电时长
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(floatTime));                //浮充时长
        tmpbuf.putShort(FBS_ComBase.changeDoubleToShort(chargeStopCurr*10));    //截止电流
        tmpbuf.putShort(FBS_ComBase.changeDoubleToShort(groupHighVol*10));        //组端上限
        tmpbuf.putShort(FBS_ComBase.changeDoubleToShort(monHighVol*100));        //单体上限
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(monHighVolCount));            //单体上限数量
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(cycleStart));                //活化起点
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(cycleTimes));                //活化次数
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(waitdisTime));                //充完静置
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(waitchrTime));                //放完静置
        tmpbuf.flip();
        return tmpbuf;
    }
    @Override
    public String toString() {
        return "DischargeParam [battName=" + battName + ", byteName=" + Arrays.toString(byteName) + ", param_index="
                + param_index + ", battStdCap=" + battStdCap + ", hourState=" + hourState + ", disChargeCurr="
                + disChargeCurr + ", disChargeCap=" + disChargeCap + ", disTime=" + disTime + ", monVolLow=" + monVolLow
                + ", groupVolLow=" + groupVolLow + ", monCount=" + monCount + ", groupCount=" + groupCount
                + ", monVolLowCount=" + monVolLowCount + ", dcVolHighLimit=" + dcVolHighLimit + ", testType=" + testType
                + ", dischargePower=" + dischargePower + ", chargeCurr=" + chargeCurr + ", chargeVol=" + chargeVol
                + ", floatVol=" + floatVol + ", chargeTime=" + chargeTime + ", floatTime=" + floatTime
                + ", chargeStopCurr=" + chargeStopCurr + ", groupHighVol=" + groupHighVol + ", monHighVol=" + monHighVol
                + ", monHighVolCount=" + monHighVolCount + ", cycleStart=" + cycleStart + ", cycleTimes=" + cycleTimes
                + ", waitdisTime=" + waitdisTime + ", waitchrTime=" + waitchrTime + "]";
    }
}
platforms/android/app/src/main/java/com/mode/BattTestRtData.java
New file
@@ -0,0 +1,66 @@
package com.mode;
import com.util.FBS_ComBase;
import java.nio.ByteBuffer;
import java.util.Date;
public class BattTestRtData {
    private final int BYTE_LEN = 28;
    public double groupVol;                        //在线电压(0.1V)
    public double tatalVol;                        //总电压(0.1V)
    public Date nowDate;                        //标准时间
    public String chageDate;                    //充电时间(时:分:秒)
    public int btnState;                        //按键状态(0:停止      1:暂停      2:放电       3:充电        4:等待充电)
    public int lowerCount;                        //已到下限单体数量
    public double chargeCurr;                    //充电电流(0.1A)
    public double testCap;                        //已放容量(1AH)
    public int maxVolNum;                        //最高单体号
    public double maxVol;                        //最高单体电压(0.001V)
    public int minVolNum;                        //最低单体号
    public double minVol;                        //最低单体电压(0.001V)
    public boolean putByteBuffer(ByteBuffer bf) {
        if(bf.limit()<BYTE_LEN) {
            return false;
        }
        ByteBuffer tmpbuf = bf;
        tmpbuf.position(0);
        groupVol = FBS_ComBase.changeShortToDouble(bf.getShort())/10;                //在线电压(0.1V)
        tatalVol = FBS_ComBase.changeShortToDouble(bf.getShort())/10;                //总电压(0.1V)
        int year = FBS_ComBase.changeByteToInt(bf.get());
        int month = FBS_ComBase.changeByteToInt(bf.get());
        int day = FBS_ComBase.changeByteToInt(bf.get());
        int hour = FBS_ComBase.changeByteToInt(bf.get());
        int min = FBS_ComBase.changeByteToInt(bf.get());
        int sec = FBS_ComBase.changeByteToInt(bf.get());
        System.out.println(year+":"+month+":"+day+":"+hour+":"+min+":"+sec);
        //nowDate = Com.getDateTimeFromStr(dt, Com.DTF_YMDhms);
        int hour1 = FBS_ComBase.changeByteToInt(bf.get());
        int min1 = FBS_ComBase.changeByteToInt(bf.get());
        int sec1 = FBS_ComBase.changeByteToInt(bf.get());
        chageDate = hour1+":"+min1+":"+sec1;                                        //充电时间(时:分:秒)
        btnState = FBS_ComBase.changeByteToInt(bf.get());                            //按键状态(0:停止      1:暂停      2:放电       3:充电        4:等待充电)
        lowerCount = FBS_ComBase.changeShortToInt(bf.getShort());                    //已到下限单体数量
        chargeCurr = FBS_ComBase.changeShortToDouble(bf.getShort())/10;                //充电电流(0.1A)
        testCap = FBS_ComBase.changeShortToInt(bf.getShort());                        //已放容量(1AH)
        maxVolNum = FBS_ComBase.changeShortToInt(bf.getShort());                    //最高单体号
        maxVol = FBS_ComBase.changeShortToDouble(bf.getShort())/1000;                //最高单体电压(0.001V)
        minVolNum = FBS_ComBase.changeShortToInt(bf.getShort());                    //最低单体号
        minVol = FBS_ComBase.changeShortToDouble(bf.getShort())/1000;                //最低单体电压(0.001V)
        return true;
    }
    @Override
    public String toString() {
        return "DischargeData [groupVol=" + groupVol + ", tatalVol=" + tatalVol + ", nowDate=" + nowDate
                + ", chageDate=" + chageDate + ", btnState=" + btnState + ", lowerCount=" + lowerCount + ", chargeCurr="
                + chargeCurr + ", testCap=" + testCap + ", maxVolNum=" + maxVolNum + ", maxVol=" + maxVol
                + ", minVolNum=" + minVolNum + ", minVol=" + minVol + "]";
    }
}
platforms/android/app/src/main/java/com/mode/ServiceModel.java
New file
@@ -0,0 +1,88 @@
package com.mode;
import android.os.Handler;
import android.webkit.JavascriptInterface;
import com.google.gson.Gson;
import com.util.FBS_ComBase;
import java.nio.ByteBuffer;
public class ServiceModel
{
    public int code;
    public int cmd;
    public String msg;
    public Object data;
    public Handler handler;
    public ServiceModel()
    {
        String msg = "";
        int code = 0;
        int cmd = 0;
        Object data = null;
        handler = null;
    }
    @JavascriptInterface
    public void setServiceModel(int cmd, Object data){
        this.cmd = cmd;
        this.data = data;
    }
    @JavascriptInterface
    public ServiceModel getServiceModel(){
        return this;
    }
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public int getCmd() {
        return cmd;
    }
    public void setCmd(int cmd) {
        this.cmd = cmd;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }
    public Handler getHandler() {
        return handler;
    }
    public void setHandler(Handler handler) {
        this.handler = handler;
    }
    @Override
    public String toString() {
        return "ServiceModel{" +
                "code=" + code +
                ", cmd=" + cmd +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                ", handler=" + handler +
        '}';
    }
}
platforms/android/app/src/main/java/com/socket/MySocketClientThread.java
New file
@@ -0,0 +1,435 @@
package com.socket;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import com.mode.BattRTData;
import com.mode.BattTestParam;
import com.mode.BattTestRtData;
import com.mode.ServiceModel;
import com.util.ComFn;
import com.util.Ecb_Aes;
import com.util.FBS_Cmd;
import com.util.FBS_ComBase;
import com.util.FBS_ComBuf;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Date;
public class MySocketClientThread extends Thread{
    private String server_ip;                       //服务器ip地址
    private int server_port = 6666;                 //设备屏监听端口
    private BattRTData battData;                    //电池实时数据
    private BattTestParam testParam;                //电池测试参数
    private BattTestRtData testRtData;              //电池测试数据
    private FBS_Cmd m_FBS_Cmd;
    private ByteBuffer bytebuffer_for_socket_RX = ByteBuffer.allocate(1500);
    public Handler mHandler = null;
    public static Socket socket;
    private Date lastConTime;                       //上一次通讯成功的时间
    private boolean thread_run_flag = true;
    public MySocketClientThread(String server_ip){
        this.server_ip = server_ip;
        battData = new BattRTData();
        testParam = new BattTestParam();
        testRtData = new BattTestRtData();
        try {
            socket = new Socket(this.server_ip, server_port);
        } catch (IOException e) {
            //e.printStackTrace();
        }
    }
    /*********************************************************************************************/
    public void run()
    {
        //初始化消息循环队列,需要在Handler创建之前
        Looper.prepare();
        mHandler = new Handler()
        {
            public void handleMessage(Message msg)
            {
                ServiceModel model = (ServiceModel)msg.obj;
                try
                {
                    if(null != model.handler)
                    {
                        ServiceModel remodel = new ServiceModel();
                        if(true == SocketComm(model.cmd, (ByteBuffer)(model.createByteBuffer()), remodel))
                        {
                            remodel.cmd = m_FBS_Cmd.CMD;
                            //--------------- 新建消息与句柄 -----------------
                            Handler handler = model.handler;
                            Message toMain = handler.obtainMessage();
                            toMain.obj = remodel;
                            handler.sendMessage(toMain);
                            //-----------------------------------------------
                            sleep(100);
                        }else{
                            remodel.cmd = model.cmd;
                            //--------------- 新建消息与句柄 -----------------
                            Handler handler = model.handler;
                            Message toMain = handler.obtainMessage();
                            toMain.obj = remodel;
                            handler.sendMessage(toMain);
                        }
                    }
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        };
        //启动子线程消息循环队列
        Looper.loop();
    }
    /**
     *     向指定的socket通道发送数据,以及接收数据
     * @return
     */
    public boolean SocketComm(int cmd,ByteBuffer byteBuffer,ServiceModel model)
    {
        boolean res_t = false;
        InputStream in = null;
        OutputStream out = null;
        try
        {
            socket.setSoTimeout(2000);
            if(this.socket != null)
            {
                in = this.socket.getInputStream();
                out = this.socket.getOutputStream();
                //----------------- clear rx buff for tcp resend packet ----------------//
                byte[] rx_buf_t = new byte[1024];
                //----------------------------------------------------------------------//
                bytebuffer_for_socket_RX.order(ByteOrder.LITTLE_ENDIAN);
                bytebuffer_for_socket_RX.clear();
                //--------------------- socket write -----------------------------------//
                //--------------------- socket write -----------------------------------//
                boolean aes_en = false;
                byte[] plain_tx_t = makeCommBuf(cmd, byteBuffer, aes_en);
                byte[] cipher_tx_t = new byte[plain_tx_t.length];
                Ecb_Aes my_aes = new Ecb_Aes();
                my_aes.ecb_encrypt(plain_tx_t, cipher_tx_t, plain_tx_t.length);
                Date d1 = new Date();
                //=====================================================================//
                /*
                for(int n=0; n<3; n++) {
                    out.write(b);
                    out.flush();
                    //-----------------------------------------------------------------//
                    try {
                        while(true) {
                            int rx_len_t = in.read(rx_buf_t);
                            if(rx_len_t > 0) {
                                if((bytebuffer_for_socket_RX.position()+rx_len_t)
                                        < (bytebuffer_for_socket_RX.capacity()-16)) {
                                    bytebuffer_for_socket_RX.put(rx_buf_t, 0, rx_len_t);
                                }
                            }
                            if(bytebuffer_for_socket_RX.position() > 8) {
                                break;
                            }
                        }
                    } catch (SocketTimeoutException soe) {
                        //soe.printStackTrace();
                    }
                    //-----------------------------------------------------------------//
                }
                //=====================================================================//
                */
                int rx_read_time_out = 0;
                //int rx_len = 0;
                System.out.println("数据长度" + plain_tx_t.length + "\t发送数据:" + ComFn.bytesToHexString(plain_tx_t, plain_tx_t.length));
                out.write(plain_tx_t);
                out.flush();
                while(true) {
                    if(in.available() > 0) {
                        rx_read_time_out = 0;
                        int rx_len_t = in.read(rx_buf_t);
                        if((bytebuffer_for_socket_RX.position()+rx_len_t)
                                < (bytebuffer_for_socket_RX.capacity()-1)) {
                            bytebuffer_for_socket_RX.put(rx_buf_t, 0, rx_len_t);
                        }
                        //bytebuffer_for_socket_RX.put((byte)in.read());
                    } else {
                        rx_read_time_out++;
                        if((bytebuffer_for_socket_RX.position() >= 8) && (rx_read_time_out>10)){
                            //    res = true;
                            break;
                        }
                        if(rx_read_time_out > 220) {
                            break;
                        }
                    }
                    Thread.sleep(10);
                }
                bytebuffer_for_socket_RX.flip();
                Date d2 = new Date();
                long comm_tms = (d2.getTime() - d1.getTime());
                if(comm_tms < 200) {
                    Thread.sleep(200 - comm_tms);
                }
                /*
                System.out.println(this.getName()
                                    + "  dev_id: " + m_StatAndParam.dev_id
                                    + "  d2-d1:" + (comm_tms)+"ms"
                                    + "  rx_len:" + bytebuffer_for_socket_RX.limit()
                                    + "  tx_count:" + m_FBS_VCData.m_SysState.CommCount
                                    + "  rx_err_sum:" + m_FBS_VCData.m_SysState.ErrCommCount
                                    + "  rx_err_count:" + rx_errcount_for_live_of_thread
                                    + Com.getNowTimeWithAt());
                */
                byte[] cipher_buf = new byte[bytebuffer_for_socket_RX.limit()];
                byte[] plain_buf = new byte[bytebuffer_for_socket_RX.limit()];
                bytebuffer_for_socket_RX.get(cipher_buf);
                my_aes.ecb_decrypt(cipher_buf, plain_buf, cipher_buf.length);
                System.err.println("数据长度"+cipher_buf.length+"\t返回数据:"+ ComFn.bytesToHexString(cipher_buf, cipher_buf.length));
                //Log.e(TAG, "SocketComm: "+ComFn.bytesToHexString(plain_buf, plain_buf.length));
                if(true == getDataFromCommBuf(cipher_buf,model)) {
                    res_t = true;
                    model.code = 1;
                } else {
                    res_t = false;
                    model.code = 0;
                }
            } else {
                //System.out.println(this.getName() + "-------socket  异常关闭-------" + Com.getNowTimeWithAt());
                thread_run_flag = false;
            }
        } catch (IOException | InterruptedException e) {
            thread_run_flag = false;
        } finally {
            if(in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(!thread_run_flag){
                reConnectDevice();
            }
        }
        return res_t;
    }
    /**
     * 根据指定的命令构造byteBuffer
     * @return
     */
    public ByteBuffer createByteBuffer(ServiceModel model){
        ByteBuffer buffer = ByteBuffer.allocate(0);
        if( FBS_ComBase.CMD_HEARTBEAT == model.cmd
            ||
        ){
        }else if(FBS_ComBase.CMD_CREATENEWBATT == model.cmd){
            //新建电池组
            testParam.battName = model.msg;
            buffer = testParam.getNewBattByteBuffer();
        }
        return buffer;
    }
    /*********************************************************************************************/
    public byte[] makeCommBuf(final int cmd, ByteBuffer bf, boolean aes_en)
    {
        ByteBuffer bbf = FBS_ComBuf.makeFbs9100CommBuf(0xFF, cmd, bf, aes_en);
        byte byte_rest[] = new byte[bbf.limit()];
        bbf.get(byte_rest);
        return byte_rest;
    }
    /*********************************************************************************************/
    /**
     *   重新连接设备
     */
    public void reConnectDevice(){
        if(socket != null){
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            socket = new Socket(server_ip, server_port);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /*********************************************************************************************/
    public Boolean getDataFromCommBuf(final byte[] bytes)
    {
        returnmodel = new ServiceModel();
        boolean isSuccess = false;
        ByteBuffer bf = ByteBuffer.allocate(bytes.length);
        bf.order(ByteOrder.LITTLE_ENDIAN);
        bf.put(bytes);
        bf.flip();
        String msg = "";
        if(true == m_FBS_Cmd.putByteBuffer(bf))
        {
            lastConTime = new Date();
            //---------------------  心跳包测试    ----------------------------------
            if(FBS_ComBase.CMD_HEARTBEAT == m_FBS_Cmd.CMD) {
                if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
                    byte[] b = new byte[bf.limit()];
                    bf.get(b);
                    try {
                        System.out.println("当前电池组是:"+new String(b,"utf-8"));
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    isSuccess = true;
                    System.out.println("获取心跳包成功");
                }
            }
            //---------------------  新建电池组    ----------------------------------
            else if(FBS_ComBase.CMD_CREATENEWBATT == m_FBS_Cmd.CMD) {
                if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
                    isSuccess = true;
                    System.out.println("新建电池组成功");
                }
            }
            //---------------------  切换电池组    ----------------------------------
            else if(FBS_ComBase.CMD_CHANGEBATT == m_FBS_Cmd.CMD) {
                if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
                    isSuccess = true;
                    System.out.println("切换电池组成功");
                }
            }
            //---------------------  删除电池组    ----------------------------------
            else if(FBS_ComBase.CMD_DELETENOWBATT == m_FBS_Cmd.CMD) {
                if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
                    isSuccess = true;
                    System.out.println("删除电池组成功");
                }
            }
            //---------------------  获取单体数据    ----------------------------------------------
            else if(FBS_ComBase.CMD_GETBATTDATA == m_FBS_Cmd.CMD) {
                System.err.println("获取单体数据");
                if(battData.putByteBuffer(bf, m_FBS_Cmd.ByteLen-m_FBS_Cmd.BYTE_LEN)) {
                    System.out.println("获取单体数据成功");
                }
            }
            //---------------------  获取放电参数    ----------------------------------------------
            else if(FBS_ComBase.CMD_GETDISCHARGEPARAM == m_FBS_Cmd.CMD) {
                if(testParam.putByteBuffer(bf)) {
                    System.out.println("获取放电参数成功");
                    System.out.println(testParam);
                }
            }
            //---------------------- 设置放电参数 --------------------------------------------------
            else if(FBS_ComBase.CMD_SETDISCHARGEPARAM == m_FBS_Cmd.CMD) {
                if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
                    isSuccess = true;
                    System.out.println("设置参数成功");
                }
            }
            //---------------------  启动放电    ----------------------------------
            else if(FBS_ComBase.CMD_STARTDISCHARGE == m_FBS_Cmd.CMD) {
                if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
                    isSuccess = true;
                    System.out.println("启动放电成功");
                }
            }
            //---------------------  放电暂停    ----------------------------------
            else if(FBS_ComBase.CMD_PAUSEDISCHARGE == m_FBS_Cmd.CMD) {
                if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
                    isSuccess = true;
                    System.out.println("暂停放电成功");
                }
            }
            //---------------------  停止放电    ----------------------------------
            else if(FBS_ComBase.CMD_STOPDISCHARGE == m_FBS_Cmd.CMD) {
                if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
                    isSuccess = true;
                    System.out.println("停止放电成功");
                }
            }
            //---------------------  获取放电数据    ----------------------------------
            else if(FBS_ComBase.CMD_GETDISCHARGEDATA == m_FBS_Cmd.CMD) {
                if(testRtData.putByteBuffer(bf)) {
                    isSuccess = true;
                    System.out.println("获取放电数据成功"+testRtData);
                }
            }
            //---------------------  启动充电    ----------------------------------
            else if(FBS_ComBase.CMD_STARTCHARGE== m_FBS_Cmd.CMD) {
                if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
                    isSuccess = true;
                    System.out.println("启动充电成功");
                }
            }
            //---------------------  暂停充电    ----------------------------------
            else if(FBS_ComBase.CMD_PAUSECHARGE== m_FBS_Cmd.CMD) {
                if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
                    isSuccess = true;
                    System.out.println("暂停充电成功");
                }
            }
            //---------------------  停止充电    ----------------------------------
            else if(FBS_ComBase.CMD_STOPCHARGE== m_FBS_Cmd.CMD) {
                if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
                    isSuccess = true;
                    System.out.println("停止充电成功");
                }
            }
            //---------------------  获取充电数据    ----------------------------------
            else if(FBS_ComBase.CMD_GETCHARGEDATA == m_FBS_Cmd.CMD) {
                if(testRtData.putByteBuffer(bf)) {
                    isSuccess = true;
                    System.out.println("获取充电数据成功"+testRtData);
                }
            }
            //---------------------  新建电池组组名    ----------------------------------------------
        }
        return isSuccess;
    }
}
platforms/android/app/src/main/java/com/util/Com.java
New file
@@ -0,0 +1,159 @@
package com.util;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Com {
    final public static int UploadData_ClientType_BS_CLI = 0;
    final public static int UploadData_ClientType_CS_CLI = 1;
    final public static int UploadData_ClientType_CS_SVR = 2;
    final public static String DTF_YMDhms = "yyyy-MM-dd HH:mm:ss";
    final public static String DTF_YMDhm = "yyyy-MM-dd HH:mm";
    final public static String DTF_YMDh = "yyyy-MM-dd HH";
    final public static String DTF_YMD = "yyyy-MM-dd";
    final public static String DTFYMD = "yyyyMMdd";
    final public static String DTF_hms = "HH:mm:ss";
    final public static String DTF_YMD_h_m_s = "yyyy-MM-dd+HH_mm_ss";
    //final public static DateFormat DateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    /**
     * 将传入的时间转换成指定的的时间格式并返回时间格式化之后的字符串
     * @param dt        需要转换的时间
     * @param format    格式化字符串
     * @return
     */
    public static String getDateTimeFormat(Date dt, String format){
        DateFormat dtf = new SimpleDateFormat(format);
        return dtf.format(dt);
    }
    /**
     * 将传入的字符串按指定的格式解析成时间类型并返回
     * @param dt       需要解析的字符串
     * @param format   指定的时间格式
     * @return
     */
    public static Date getDateTimeFromStr(String dt, String format){
        DateFormat dtf = new SimpleDateFormat(format);
        Date date = new Date();
        try {
            date = dtf.parse(dt);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
    public static String getNowTimeWithAt() {
        return " @ " + Com.getDateTimeFormat(new Date(), Com.DTF_YMDhms);
    }
    /**
     * 判断number参数是否是整型数表示方式
     * @param number
     * @return
     */
    public static boolean isIntegerNumber(String number){
        number = number.trim();
        String intNumRegex = "\\-{0,1}\\d+";    //整数的正则表达式
        if(number.matches(intNumRegex))
            return true;
        else
            return false;
    }
    /**
     * 判断number参数是否是浮点数表示方式
     * @param numbe
     * @return
     */
    public static boolean isFloatPointNumber(String number){
        number = number.trim();
        String intNumRegex = "\\-{0,1}\\d+";                //整数的正则表达式
        String pointPrefix = "(\\-|\\+){0,1}\\d*\\.\\d+";    //浮点数的正则表达式-小数点在中间与前面
        String pointSuffix = "(\\-|\\+){0,1}\\d+\\.";        //浮点数的正则表达式-小数点在后面
        if(number.matches(intNumRegex) || number.matches(pointPrefix) || number.matches(pointSuffix))
            return true;
        else
            return false;
    }
    /**
     * 判断number参数是否是日期表示方式
     * @param str
     * @return
     */
    public static boolean isValidDate(String str, String format) {
        boolean convertSuccess = true;
        try {
            //DateTimeFormat.setLenient(false);
            DateFormat dtf = new SimpleDateFormat(format);
            dtf.parse(str);
        } catch (ParseException e) {
            convertSuccess = false;
        }
        return convertSuccess;
    }
    /**
     * 设置系统的日期时间
     * @param str
     * @return
     */
    public static void setDateTime(Date ts){
        String osName = System.getProperty("os.name");
        String cmd = "";
        try {
            if (osName.matches("^(?i)Windows.*$")) {// Window 系统
                // 格式 HH:mm:ss
                cmd = "cmd /c time " + getDateTimeFormat(ts, Com.DTF_hms);
                Runtime.getRuntime().exec(cmd);
                // 格式:yyyy-MM-dd
                cmd = "cmd /c date " + getDateTimeFormat(ts, Com.DTF_YMD);
                Runtime.getRuntime().exec(cmd);
            } else {// Linux 系统
                // 格式:yyyyMMdd
                cmd = "date -s " + getDateTimeFormat(ts, Com.DTFYMD);
                Runtime.getRuntime().exec(cmd);
                // 格式 HH:mm:ss
                cmd = "date -s " + getDateTimeFormat(ts, Com.DTF_hms);
                Runtime.getRuntime().exec(cmd);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     *
     * @param
     * @return
     */
    public static void getIPFromStr(String ipstr, byte ip[])
    {
        try
        {
            for(int n=0; n < 3; n++)
            {
                int index = ipstr.indexOf('.');
                if(index > 0)
                    ip[n] = (byte)Integer.parseInt(ipstr.substring(0, index));
                ipstr = ipstr.substring(index+1);
            }
            ip[3] = (byte)Integer.parseInt(ipstr);
            //System.out.println((ip[0]&0xFF) + ": "+(ip[1]&0xFF) + ": "+(ip[2]&0xFF)+ ": "+(ip[3]&0xFF));
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
    }
}
platforms/android/app/src/main/java/com/util/ComFn.java
New file
@@ -0,0 +1,19 @@
package com.util;
public class ComFn {
    public static String bytesToHexString(byte[] src, int len){
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || len <= 0) {
            return null;
        }
        for (int i = 0; i < len; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v).toUpperCase();
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv + " ");
        }
        return stringBuilder.toString();
    }
}
platforms/android/app/src/main/java/com/util/Ecb_Aes.java
New file
@@ -0,0 +1,570 @@
package com.util;
public class Ecb_Aes {
    //AES block size in bytes
    public final static int AES_BLOCK_SIZE = 16;
    //Total number of rounds for AES-128
    public final static int AES_NUM_OF_ROUNDS = 10;
    //Key schedule size
    public final static int AES_KEY_SCHEDULE_SIZE = ((AES_BLOCK_SIZE) * (AES_NUM_OF_ROUNDS + 1));
    /*  S-box in hexadecimal format */
    int[] sbox =   {
        //0     1    2      3     4    5     6     7      8    9     A      B    C     D     E     F
        0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,  //0
        0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,  //1
        0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,  //2
        0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,  //3
        0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,  //4
        0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,  //5
        0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,  //6
        0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,  //7
        0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,  //8
        0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,  //9
        0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,  //A
        0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,  //B
        0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,  //C
        0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,  //D
        0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,  //E
        0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16   //F
    };
    /* Inverse S-box in hexadecimal format */
    int[] inv_sbox = {
        //0     1    2      3     4    5     6     7      8    9     A      B    C     D     E     F
        0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,  //0
        0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,  //1
        0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,  //2
        0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,  //3
        0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,  //4
        0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,  //5
        0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,  //6
        0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,  //7
        0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,  //8
        0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,  //9
        0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,  //A
        0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,  //B
        0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,  //C
        0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,  //D
        0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,  //E
        0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d   //F
    };
    /* Round constant for Key Expansion */
    byte[] RCon = {
        (byte) 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, (byte) 0x80, 0x1b, 0x36
    };
    /* Array to store values after key expansion */
    byte[] key_schedule = new byte[AES_KEY_SCHEDULE_SIZE];
    /* Key Initialization vector */
    byte[] key_vectors = {(byte) 0xf7, (byte) 0xe7, 0x09, (byte) 0xcf,
                            0x4f, (byte) 0xc3, 0x15, (byte) 0x88,
                            0x28, (byte) 0xae, (byte) 0xd2, (byte) 0xa6,
                            0x15, 0x16, (byte) 0xab, (byte) 0xac};
    /*
    byte[] key_vectors = {(byte) 0xac, (byte) 0xe7, 0x15, 0x16,
                             0x28, (byte) 0xae, (byte) 0xd2, (byte) 0xa6,
                             (byte) 0xab, (byte) 0xf7, 0x15, (byte) 0x88,
                             0x09, (byte) 0xcf, 0x4f, (byte) 0xc3};
    */
    public Ecb_Aes() {
        KeyExpansion(key_schedule, key_vectors);
    }
    void KeyExpansion(byte[] round_key, byte[] key)
    {
        byte i, temp;
        //Retain the initial for round 0
        for ( i = 0; i < 16; i++){
            round_key[ i ] = key[ i ];
        }
        // Compute Key schedule of block size for each round
        for ( i = 1; i < (AES_NUM_OF_ROUNDS + 1); i++){
            temp = round_key[ i*16 - 4 ];
            round_key[i*16 +  0] = (byte) (sbox[ round_key[i*16 - 3]&0xFF ] ^ round_key[(i-1)*16 + 0] ^ RCon[ i ]);
            round_key[i*16 +  1] = (byte) (sbox[ round_key[i*16 - 2]&0xFF ] ^ round_key[(i-1)*16 + 1]);
            round_key[i*16 +  2] = (byte) (sbox[ round_key[i*16 - 1]&0xFF ] ^ round_key[(i-1)*16 + 2]);
            round_key[i*16 +  3] = (byte) (sbox[ temp&0xFF ] ^ round_key[ (i-1)*16 + 3 ]);
            round_key[i*16 +  4] = (byte) (round_key[(i-1)*16 + 4] ^ round_key[i*16 + 0]);
            round_key[i*16 +  5] = (byte) (round_key[(i-1)*16 + 5] ^ round_key[i*16 + 1]);
            round_key[i*16 +  6] = (byte) (round_key[(i-1)*16 + 6] ^ round_key[i*16 + 2]);
            round_key[i*16 +  7] = (byte) (round_key[(i-1)*16 + 7] ^ round_key[i*16 + 3]);
            round_key[i*16 +  8] = (byte) (round_key[(i-1)*16 + 8] ^ round_key[i*16 + 4]);
            round_key[i*16 +  9] = (byte) (round_key[(i-1)*16 + 9] ^ round_key[i*16 + 5]);
            round_key[i*16 + 10] = (byte) (round_key[(i-1)*16 +10] ^ round_key[i*16 + 6]);
            round_key[i*16 + 11] = (byte) (round_key[(i-1)*16 +11] ^ round_key[i*16 + 7]);
            round_key[i*16 + 12] = (byte) (round_key[(i-1)*16 +12] ^ round_key[i*16 + 8]);
            round_key[i*16 + 13] = (byte) (round_key[(i-1)*16 +13] ^ round_key[i*16 + 9]);
            round_key[i*16 + 14] = (byte) (round_key[(i-1)*16 +14] ^ round_key[i*16 +10]);
            round_key[i*16 + 15] = (byte) (round_key[(i-1)*16 +15] ^ round_key[i*16 +11]);
        }
    }
    void SubBytes_ShiftRows(byte[] state)
    {
        byte temp1 = 0,temp2 = 0;
        // row 0
        state[0]  = (byte) (sbox[ state[0] & 0xFF] & 0xFF);
        state[4]  = (byte) (sbox[ state[4] & 0xFF ] & 0xFF);
        state[8]  = (byte) (sbox[ state[8] & 0xFF ] & 0xFF);
        state[12] = (byte) (sbox[ state[12] & 0xFF ] & 0xFF);
        // row 1
        temp1 = (byte) (sbox[ state[1] & 0xFF ] & 0xFF);
        state[1]  = (byte) (sbox[ state[5] & 0xFF ] & 0xFF);
        state[5]  = (byte) (sbox[ state[9] & 0xFF ] & 0xFF);
        state[9]  = (byte) (sbox[ state[13] & 0xFF] & 0xFF);
        state[13] = temp1;
        // row 2
        temp1 = (byte) (sbox[ state[2] & 0xFF] & 0xFF);
        temp2 = (byte) (sbox[ state[6] & 0xFF] & 0xFF);
        state[2]  = (byte) (sbox[ state[10] & 0xFF ] & 0xFF);
        state[6]  = (byte) (sbox[ state[14] & 0xFF ] & 0xFF);
        state[10] = temp1;
        state[14] = temp2;
        // row 3
        temp1 = (byte) (sbox[ state[15] & 0xFF ] & 0xFF);
        state[15]  = (byte) (sbox[ state[11] & 0xFF ] & 0xFF);
        state[11]  = (byte) (sbox[ state[7] & 0xFF ] & 0xFF);
        state[7]  = (byte) (sbox[ state[3] & 0xFF ] & 0xFF);
        state[3]  = temp1;
    }
    byte xtime(byte value)
    {
        if ( (value >> 7) != 0 ){
            value = (byte) (value << 1);
            return (byte) ( value ^ 0x1b );
        } else {
            return (byte) (value << 1);
        }
    }
    void MixColumnns(byte[] state)
    {
        byte temp1 = 0,temp2 = 0,temp3 = 0;
        // col 1
        temp1 = (byte) (state[0] ^ state[1] ^ state[2] ^ state[3]);
        temp2 = state[0];
        temp3 = (byte) (state[0] ^ state[1]);
        temp3 = xtime( temp3 );
        state[0] = (byte) (state[0] ^ temp3 ^ temp1);
        temp3 = (byte) (state[1] ^ state[2]);
        temp3 = xtime( temp3 );
        state[1] = (byte) (state[1] ^ temp3 ^ temp1);
        temp3 = (byte) (state[2] ^ state[3]);
        temp3 = xtime( temp3 );
        state[2] = (byte) (state[2] ^ temp3 ^ temp1);
        temp3 = (byte) (state[3] ^ temp2);
        temp3 = xtime( temp3 );
        state[3] = (byte) (state[3] ^ temp3 ^ temp1);
        // col 2
        temp1 = (byte) (state[4] ^ state[5] ^ state[6] ^ state[7]);
        temp2 = state[4];
        temp3 = (byte) (state[4] ^state[5]);
        temp3 = xtime( temp3 );
        state[4] = (byte) (state[4] ^ temp3 ^ temp1);
        temp3 = (byte) (state[5] ^state[6]);
        temp3 = xtime( temp3 );
        state[5] = (byte) (state[5] ^ temp3 ^ temp1);
        temp3 = (byte) (state[6] ^ state[7]);
        temp3 = xtime( temp3 );
        state[6] = (byte) (state[6] ^ temp3 ^ temp1);
        temp3 = (byte) (state[7] ^ temp2);
        temp3 = xtime( temp3 );
        state[7] = (byte) (state[7] ^ temp3 ^ temp1);
        // col 3
        temp1 = (byte) (state[8] ^ state[9] ^ state[10] ^ state[11]);
        temp2 = state[8];
        temp3 = (byte) (state[8] ^ state[9]);
        temp3 = xtime( temp3 );
        state[8] = (byte) (state[8] ^ temp3 ^ temp1);
        temp3 = (byte) (state[9] ^ state[10]);
        temp3 = xtime( temp3 );
        state[9] = (byte) (state[9] ^ temp3 ^ temp1);
        temp3 = (byte) (state[10]^state[11]);
        temp3 = xtime( temp3 );
        state[10] = (byte) (state[10] ^ temp3 ^ temp1);
        temp3 = (byte) (state[11] ^ temp2);
        temp3 = xtime( temp3 );
        state[11] = (byte) (state[11] ^ temp3 ^ temp1);
        // col 4
        temp1 = (byte) (state[12 ] ^ state[13] ^ state[14] ^ state[15]);
        temp2 = state[12];
        temp3 = (byte) (state[12] ^ state[13]);
        temp3 = xtime( temp3 );
        state[12] = (byte) (state[12] ^ temp3 ^ temp1);
        temp3 = (byte) (state[13] ^ state[14]);
        temp3 = xtime( temp3 );
        state[13] = (byte) (state[13] ^ temp3 ^ temp1);
        temp3 = (byte) (state[14] ^ state[15]);
        temp3 = xtime( temp3 );
        state[14] = (byte) (state[14] ^ temp3 ^ temp1);
        temp3 = (byte) (state[15] ^ temp2);
        temp3 = xtime( temp3 );
        state[15] = (byte) (state[15] ^ temp3 ^ temp1);
    }
    void AddRoundKey(byte[] state, byte round)
    {
        // row 0
        state[0]  =  (byte) ( state[0] ^ key_schedule[(round * 16)] );
        state[4]  =  (byte) ( state[4] ^ key_schedule[(round * 16) + 4] );
        state[8]  =  (byte) ( state[8] ^ key_schedule[(round * 16) + 8] );
        state[12] =  (byte) ( state[12] ^ key_schedule[(round * 16) + 12] );
        // row 1
        state[1]  =  (byte) ( state[1] ^ key_schedule[(round * 16) + 1] );
        state[5]  =  (byte) ( state[5] ^ key_schedule[(round * 16) + 5] );
        state[9]  =  (byte) ( state[9] ^ key_schedule[(round * 16) + 9] );
        state[13] =  (byte) ( state[13] ^ key_schedule[(round * 16) +13] );
        // row 2
        state[2]  =  (byte) ( state[2] ^ key_schedule[(round * 16) + 2] );
        state[6]  =  (byte) ( state[6] ^ key_schedule[(round * 16) + 6] );
        state[10] =  (byte) ( state[10] ^ key_schedule[(round * 16) + 10] );
        state[14] =  (byte) ( state[14] ^ key_schedule[(round * 16) + 14] );
        // row 3
        state[3]  =  (byte) ( state[3] ^ key_schedule[(round * 16) + 3] );
        state[7]  =  (byte) ( state[7] ^ key_schedule[(round * 16) + 7] );
        state[11] =  (byte) ( state[11] ^ key_schedule[(round * 16) + 11] );
        state[15] =  (byte) ( state[15] ^ key_schedule[(round * 16) + 15] );
    }
    byte aes_cipher(byte[] plainText, byte[] state)
    {
        byte byte_count = 0;
        byte round = 0;
        // Check if the aes_init() is called for key expansion
        //if(aes_key_ready != true)
        //    return ERR_NO_KEY;
        //Copy input buffer to state to form the cipher state
        for (byte_count =0; byte_count < AES_BLOCK_SIZE; byte_count++){
            state[byte_count] = plainText[byte_count];
        }
        // Round 0
        state[0] ^= key_schedule[0];
        state[1] ^= key_schedule[1];
        state[2] ^= key_schedule[2];
        state[3] ^= key_schedule[3];
        state[4] ^= key_schedule[4];
        state[5] ^= key_schedule[5];
        state[6] ^= key_schedule[6];
        state[7] ^= key_schedule[7];
        state[8] ^= key_schedule[8];
        state[9] ^= key_schedule[9];
        state[10] ^= key_schedule[10];
        state[11] ^= key_schedule[11];
        state[12] ^= key_schedule[12];
        state[13] ^= key_schedule[13];
        state[14] ^= key_schedule[14];
        state[15] ^= key_schedule[15];
        //Round 1 to 9
        for (round = 1; round < 10; round ++){
            /* Sub Bytes and Shift Rows */
            SubBytes_ShiftRows(state);
            /* Mix Columns */
            MixColumnns(state);
            /* Add RoundKey */
            AddRoundKey(state,round);
        }
        // 10th round without mix columns
        round = 10;
        /* Sub Bytes and Shift Rows */
        SubBytes_ShiftRows(state);
        /* Add RoundKey */
        AddRoundKey(state,round);
        return 0;
    }
    public void ecb_encrypt(byte[] plainText, byte[] cipherText, int size)
    {
        int input_block_size = 0;
        byte block_count = 0;
        //Calculate the number of input blocks
        input_block_size = size/AES_BLOCK_SIZE;
        for(block_count = 0; block_count < input_block_size; block_count++){
            //Perform forward cipher for the input blocks
            byte[] pt = new byte[AES_BLOCK_SIZE];
            byte[] ct = new byte[AES_BLOCK_SIZE];
            for(int n=0; n<AES_BLOCK_SIZE; n++) {
                pt[n] = plainText[(block_count * AES_BLOCK_SIZE) + n];
                ct[n] = cipherText[(block_count * AES_BLOCK_SIZE) + n];
            }
            aes_cipher(pt, ct);
            for(int n=0; n<AES_BLOCK_SIZE; n++) {
                plainText[(block_count * AES_BLOCK_SIZE) + n] = pt[n];
                cipherText[(block_count * AES_BLOCK_SIZE) + n] = ct[n];
            }
        }
    }
    /*************************************************************************************************/
    /*************************************************************************************************/
    /*************************************************************************************************/
    /*************************************************************************************************/
    byte aes_inverse_cipher(byte[] cipherText, byte[] state)
    {
        byte round = 0;
        byte byte_count = 0;
        // Check if the aes_init() is called for key expansion
        //if(aes_key_ready != true)
        //    return ERR_NO_KEY;
        //Copy input buffer to state to form the plain text
        for (byte_count =0; byte_count < AES_BLOCK_SIZE; byte_count++){
            state[byte_count] = cipherText[byte_count];
        }
        // Initial addroundkey
        state[0] ^= key_schedule[160];
        state[1] ^= key_schedule[161];
        state[2] ^= key_schedule[162];
        state[3] ^= key_schedule[163];
        state[4] ^= key_schedule[164];
        state[5] ^= key_schedule[165];
        state[6] ^= key_schedule[166];
        state[7] ^= key_schedule[167];
        state[8] ^= key_schedule[168];
        state[9] ^= key_schedule[169];
        state[10] ^= key_schedule[170];
        state[11] ^= key_schedule[171];
        state[12] ^= key_schedule[172];
        state[13] ^= key_schedule[173];
        state[14] ^= key_schedule[174];
        state[15] ^= key_schedule[175];
        // Round 9 to 1
        for(round = 9; round>0; round--){
            /* Inverse Sub Bytes and Shift Rows */
            Inv_ShiftRows_SubBytes(state);
            /* Inverse Add Round Key */
            Inv_AddRoundKey(state, round);
            /* Inverse Mix Columns */
            Inv_MixColumns(state, round);
        }
        // Round 0 without mixcols
        round = 0;
        /* Inverse Sub Bytes and Shift Rows */
        Inv_ShiftRows_SubBytes(state);
        /* Inverse Add Round Key */
        Inv_AddRoundKey(state, round);
        return 0;
    }
    void Inv_ShiftRows_SubBytes(byte[] state)
    {
        byte temp1 = 0,temp2 = 0;
        // row 0
        state[0] = (byte) inv_sbox[ state[0]&0xFF ];
        state[4] = (byte) inv_sbox[ state[4]&0xFF ];
        state[8] = (byte) inv_sbox[ state[8]&0xFF ];
        state[12] = (byte) inv_sbox[ state[12]&0xFF ];
        // row 1
        temp1 = (byte) inv_sbox[ state[13]&0xFF ];
        state[13] = (byte) inv_sbox[ state[9]&0xFF ];
        state[9] = (byte) inv_sbox[ state[5]&0xFF ];
        state[5] = (byte) inv_sbox[ state[1]&0xFF ];
        state[1] = temp1;
        // row 2
        temp1 = (byte) inv_sbox[ state[2]&0xFF ] ;
        temp2 = (byte) inv_sbox[ state[6]&0xFF ] ;
        state[2] = (byte) inv_sbox[ state[10]&0xFF ] ;
        state[6] = (byte) inv_sbox[ state[14]&0xFF ] ;
        state[10] = temp1;
        state[14] = temp2;
        // row 3
        temp1 = (byte) inv_sbox[ state[3]&0xFF ];
        state[3] = (byte) inv_sbox[ state[7]&0xFF ];
        state[7] = (byte) inv_sbox[ state[11]&0xFF ] ;
        state[11] = (byte) inv_sbox[ state[15]&0xFF ] ;
        state[15] = temp1;
    }
    void Inv_AddRoundKey(byte[] state, int round)
    {
        // row 0
        state[0]  =  (byte) ( state[0] ^ key_schedule[(round * 16)] );
        state[4]  =  (byte) ( state[4] ^ key_schedule[(round * 16) + 4] );
        state[8]  =  (byte) ( state[8] ^ key_schedule[(round * 16) + 8] );
        state[12] =  (byte) ( state[12] ^ key_schedule[(round * 16) + 12] );
        // row 1
        state[1]  =  (byte) ( state[1] ^ key_schedule[(round * 16) + 1] );
        state[5]  =  (byte) ( state[5] ^ key_schedule[(round * 16) + 5] );
        state[9]  =  (byte) ( state[9] ^ key_schedule[(round * 16) + 9] );
        state[13] =  (byte) ( state[13] ^ key_schedule[(round * 16) +13] );
        // row 2
        state[2]  =  (byte) ( state[2] ^ key_schedule[(round * 16) + 2] );
        state[6]  =  (byte) ( state[6] ^ key_schedule[(round * 16) + 6] );
        state[10] =  (byte) ( state[10] ^ key_schedule[(round * 16) + 10] );
        state[14] =  (byte) ( state[14] ^ key_schedule[(round * 16) + 14] );
        // row 3
        state[3]  =  (byte) ( state[3] ^ key_schedule[(round * 16) + 3] );
        state[7]  =  (byte) ( state[7] ^ key_schedule[(round * 16) + 7] );
        state[11] =  (byte) ( state[11] ^ key_schedule[(round * 16) + 11] );
        state[15] =  (byte) ( state[15] ^ key_schedule[(round * 16) + 15] );
    }
    void Inv_MixColumns(byte[] state, int round)
    {
        byte temp1 = 0,temp2 = 0,temp3 = 0;
        //col1
        temp1 = xtime( xtime( (byte) (state[0] ^ state[2]) ) );
        temp2 = xtime( xtime( (byte) (state[1] ^ state[3]) ) );
        state[0] ^= temp1;
         state[1] ^= temp2;
        state[2] ^= temp1;
        state[3] ^= temp2;
        //col2
        temp1 = xtime( xtime( (byte) (state[4] ^ state[6]) ) );
        temp2 = xtime( xtime( (byte) (state[5] ^ state[7]) ) );
        state[4] ^= temp1;
        state[5] ^= temp2;
        state[6] ^= temp1;
        state[7] ^= temp2;
        //col3
        temp1 = xtime( xtime( (byte) (state[8] ^ state[10]) ) );
        temp2 = xtime( xtime( (byte) (state[9] ^ state[11]) ) );
        state[8] ^= temp1;
        state[9] ^= temp2;
        state[10] ^= temp1;
        state[11] ^= temp2;
        //col4
        temp1 = xtime( xtime( (byte) (state[12] ^ state[14]) ) );
        temp2 = xtime( xtime( (byte) (state[13] ^ state[15]) ) );
         state[12] ^= temp1;
         state[13] ^= temp2;
         state[14] ^= temp1;
        state[15] ^= temp2;
        // col1
        temp1 = (byte) (state[0] ^ state[1] ^ state[2] ^ state[3]);
        temp2 = state[0];
        temp3 = (byte) (state[0] ^ state[1]);
        temp3 = xtime( temp3 );
        state[0] = (byte) (state[0] ^ temp3 ^ temp1);
        temp3 = (byte) (state[1] ^ state[2]);
        temp3 = xtime( temp3 );
        state[1] = (byte) (state[1] ^ temp3 ^ temp1);
        temp3 = (byte) (state[2] ^ state[3]);
        temp3 = xtime( temp3 );
        state[2] = (byte) (state[2] ^ temp3 ^ temp1);
        temp3 = (byte) (state[3] ^ temp2);
        temp3 = xtime( temp3 );
        state[3] = (byte) (state[3] ^ temp3 ^ temp1);
        // col2
        temp1 = (byte) (state[4] ^ state[5] ^ state[6] ^ state[7]);
        temp2 = state[4];
        temp3 = (byte) (state[4] ^ state[5]);
        temp3 = xtime( temp3 );
        state[4] = (byte) (state[4] ^ temp3 ^ temp1);
        temp3 = (byte) (state[5] ^ state[6]);
        temp3 = xtime( temp3 );
        state[5] = (byte) (state[5] ^ temp3 ^ temp1);
        temp3 = (byte) (state[6] ^ state[7]);
        temp3 = xtime( temp3 );
        state[6] = (byte) (state[6] ^ temp3 ^ temp1);
        temp3 = (byte) (state[7] ^ temp2);
        temp3 = xtime( temp3 );
        state[7] = (byte) (state[7] ^ temp3 ^ temp1);
        // col3
        temp1 = (byte) (state[8] ^ state[9] ^ state[10] ^ state[11]);
        temp2 = state[8];
        temp3 = (byte) (state[8] ^state[9]);
        temp3 = xtime( temp3 );
        state[8] = (byte) (state[8] ^ temp3 ^ temp1);
        temp3 = (byte) (state[9] ^ state[10]);
        temp3 = xtime( temp3 );
        state[9] = (byte) (state[9] ^ temp3 ^ temp1);
        temp3 = (byte) (state[10] ^ state[11]);
        temp3 = xtime( temp3 );
        state[10] = (byte) (state[10] ^ temp3 ^ temp1);
        temp3 = (byte) (state[11] ^ temp2);
        temp3 = xtime( temp3 );
        state[11] = (byte) (state[11] ^ temp3 ^ temp1);
        // col4
        temp1 = (byte) (state[12] ^ state[13] ^ state[14] ^ state[15]);
        temp2 = state[12];
        temp3 = (byte) (state[12] ^ state[13]);
        temp3 = xtime( temp3 );
        state[12] = (byte) (state[12] ^ temp3 ^ temp1);
        temp3 = (byte) (state[13]^state[14]);
        temp3 = xtime( temp3 );
        state[13] = (byte) (state[13] ^ temp3 ^ temp1);
        temp3 = (byte) (state[14] ^ state[15]);
        temp3 = xtime( temp3 );
        state[14] = (byte) (state[14] ^ temp3 ^ temp1);
        temp3 = (byte) (state[15] ^ temp2);
        temp3 = xtime( temp3 );
        state[15] = (byte) (state[15] ^ temp3 ^ temp1);
    }
    public void ecb_decrypt(byte[] cipherText, byte[] plainText, int size)
    {
        int input_block_size = 0;
        byte block_count = 0;
        //Calculate the number of input blocks
        input_block_size = size/AES_BLOCK_SIZE;
        for(block_count = 0;block_count < input_block_size; block_count++){
            //Perform inverse cipher for the input blocks
            byte[] pt = new byte[AES_BLOCK_SIZE];
            byte[] ct = new byte[AES_BLOCK_SIZE];
            for(int n=0; n<AES_BLOCK_SIZE; n++) {
                pt[n] = plainText[(block_count * AES_BLOCK_SIZE) + n];
                ct[n] = cipherText[(block_count * AES_BLOCK_SIZE) + n];
            }
            aes_inverse_cipher(ct, pt);
            for(int n=0; n<AES_BLOCK_SIZE; n++) {
                plainText[(block_count * AES_BLOCK_SIZE) + n] = pt[n];
                cipherText[(block_count * AES_BLOCK_SIZE) + n] = ct[n];
            }
        }
    }
}
platforms/android/app/src/main/java/com/util/FBS_Cmd.java
New file
@@ -0,0 +1,109 @@
package com.util;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class FBS_Cmd {
    public final int BYTE_LEN = 18;
    private int SYNCode[] = {0xAA, 0xAA, 0xAA, 0xAA};            //同步码
    public int ByteLen;                                            //字节总数
    public int CMD;                                                //命令码
    public int RecState;                                        //响应信息RTN
    public int Type;                                            //响应信息CID1
    public int WorkState;                                        //响应信息CID2
    public int Alarm;                                            //响应告警值ALM
    public int Db1= 0xFF;                                        //预留1
    public int Db2;                                                //预留2
    public int Db3;                                                //预留3
    public int Db4;                                                //预留4
    private int CRC;
    public void makeCmd(int cmd, int byteLen)
    {
        ByteLen = byteLen;
        CMD = cmd;
    }
    public boolean putByteBuffer(final ByteBuffer bf)
    {
        if(bf.limit() < BYTE_LEN) {
            return false;
        }
        ByteBuffer tmpbuf = bf;
        int crc0 = tmpbuf.getShort(BYTE_LEN-2) & 0xFFFF;
        tmpbuf.position(BYTE_LEN-2);
        tmpbuf.putShort(FBS_ComBase.changeIntToShort(0));
        //System.out.println(ComFn.bytesToHexString(bf.array(), bf.array().length));;
        int crc1 = FBS_Crc16.CalCRC16(tmpbuf, tmpbuf.limit());
        //int crc1 = createCrc16(bf);
        if(crc0 != crc1) {
            System.err.println(crc0+"==="+crc1);
            return false;
        }
        tmpbuf.position(0);
        for(int n=0; n<4; n++)
            SYNCode[n] = FBS_ComBase.changeByteToInt(tmpbuf.get());
        ByteLen = FBS_ComBase.changeShortToInt(tmpbuf.getShort());                                        //字节总数
        CMD    = FBS_ComBase.changeShortToInt(tmpbuf.getShort());                                            //命令码
        RecState = FBS_ComBase.changeByteToInt(tmpbuf.get());                                            //响应信息RTN
        Type = FBS_ComBase.changeByteToInt(tmpbuf.get());                                                //响应信息CID1
        WorkState = FBS_ComBase.changeByteToInt(tmpbuf.get());                                            //响应信息CID2
        Alarm = FBS_ComBase.changeByteToInt(tmpbuf.get());                                                //响应告警值ALM
        Db1 = FBS_ComBase.changeByteToInt(tmpbuf.get());                                                //预留1
        Db2    = FBS_ComBase.changeByteToInt(tmpbuf.get());                                                //预留2
        Db3    = FBS_ComBase.changeByteToInt(tmpbuf.get());                                                //预留3
        Db4    = FBS_ComBase.changeByteToInt(tmpbuf.get());                                                //预留4
        CRC = FBS_ComBase.changeShortToInt(tmpbuf.getShort());
        tmpbuf.compact();
        tmpbuf.flip();
        return true;
    }
    public int createCrc16(ByteBuffer bf) {
        ByteBuffer temp = ByteBuffer.allocate(BYTE_LEN);
        bf.position(0);
        for(int i=0;i<BYTE_LEN-2;i++) {
            temp.put(bf.get());
        }
        temp.putShort(FBS_ComBase.changeIntToShort(0));
        return FBS_Crc16.CalCRC16(temp, BYTE_LEN);
    }
    /**
     *     构造基础发送数据
     * @return
     */
    public ByteBuffer getByteBuffer(ByteBuffer dataBuffer)
    {
        ByteBuffer bytebuffer = ByteBuffer.allocate(BYTE_LEN+dataBuffer.limit());
        bytebuffer.order(ByteOrder.LITTLE_ENDIAN);
        bytebuffer.position(0);
        for(int n=0; n<4; n++)
            bytebuffer.put(FBS_ComBase.changeIntToByte(SYNCode[n]));
        bytebuffer.putShort(FBS_ComBase.changeIntToShort(BYTE_LEN+dataBuffer.limit()));
        bytebuffer.putShort(FBS_ComBase.changeIntToShort(CMD));
        bytebuffer.put(FBS_ComBase.changeIntToByte(RecState));
        bytebuffer.put(FBS_ComBase.changeIntToByte(Type));
        bytebuffer.put(FBS_ComBase.changeIntToByte(WorkState));
        bytebuffer.put(FBS_ComBase.changeIntToByte(Alarm));
        bytebuffer.put(FBS_ComBase.changeIntToByte(Db1));
        bytebuffer.put(FBS_ComBase.changeIntToByte(Db2));
        bytebuffer.put(FBS_ComBase.changeIntToByte(Db3));
        bytebuffer.put(FBS_ComBase.changeIntToByte(Db4));
        int position = bytebuffer.position();
        bytebuffer.putShort(FBS_ComBase.changeIntToShort(0));
        bytebuffer.put(dataBuffer.array());
        CRC = FBS_Crc16.CalCRC16(bytebuffer, bytebuffer.position());
        bytebuffer.position(position);
        bytebuffer.putShort(FBS_ComBase.changeIntToShort(CRC));
        //bytebuffer.putShort((short)0xA094);
        bytebuffer.position(bytebuffer.limit());
        bytebuffer.flip();
        return bytebuffer;
    }
}
platforms/android/app/src/main/java/com/util/FBS_ComBase.java
New file
@@ -0,0 +1,307 @@
package com.util;
public class FBS_ComBase
{
    public static final int     BattGroupCountMax                =    4;
    public static final int     MonomerCountMax                    =    480;
    public static final int     FBOMonomerCountMax                 =   300;
    public static final int     CMD_STARTCNNECT                   =   0x01;
    //----------------------------------------------------------------------------
    public static final int     CMD_NULL                        =    0x00;
    //----------------------------------------------------------------------------
    //------------ 重启FBS9100设备 ------------------------------------------------
    public static final int     CMD_ResetSystem                    =     0x10;
    //------------ 升级FBS9100软件 ------------------------------------------------
    public static final int     CMD_SystemUpdate                =    0x11;
    //----------------------------------------------------------------------------
    //------------ 读取设备版本号、实时任务列表等 ----------------------------------
    public static final int     CMD_GetDeviceInf                =    0x15;
    public static final int     CMD_GetDeviceTaskInf            =    0x17;
    public static final int        CMD_GetSyslogFileLen            =    0x18;
    public static final int        CMD_GetSyslogFileStr            =    0x19;
    public static final int        CMD_ClearSyslogFile                =    0x1A;
    public static final int      CMD_Connect                     =    0x20;
    public static final int      CMD_GetState                     =    0x22;
    //----------------------------------------------------------------------------
    //------------ 启动放电测试和读取设置参数,读取放电测试状态----------------------
    public static final int     CMD_StartDischarge                =    0x25;
    public static final int     CMD_SetDischargeParm            =    0x28;
    public static final int     CMD_GetDischargeParm            =    0x29;
    public static final int     CMD_GetDischargeState            =    0x31;
    //----------------------------------------------------------------------------
    //------------ 启动内阻测试和读取内阻测试状态-----------------------------------
    public static final int     CMD_StartResDischarge            =    0x32;
    public static final int        CMD_GetResTestState                =    0x34;
    //-----------------------------------------------------------------------------
    //------------ 读取和设置电池参数-----------------------------------------------
    public static final int        CMD_GetBattParam                =    0x36;
    public static final int        CMD_SetBattParam                =    0x37;
    //----------------------------------------------------------------------------
    //------------ 启动充电测试和读取设置参数,读取充电测试状态-----------------------
    public static final int     CMD_StartCharge                    =    0x40;
    public static final int      CMD_SetChargeParm                =    0x43;
    public static final int      CMD_GetChargeParm                =    0x44;
    public static final int     CMD_GetChargeState                =    0x46;
    //-----------------------------------------------------------------------------
    //------------ 停止任何的测试 --------------------------------------------------
    public static final int     CMD_Stop                        =    0x53;            //停止测试
    public static final int     CMD_Suspended                    =   0x54;            //暂停测试
    //----------------------------------------------------------------------------
    //------------ 读取电压电流、充放电测试、内阻测试数据 ---------------------------
    public static final int     CMD_GetVIData                    =    0x60;
    public static final int      CMD_GetMonomerData                =    0x61;
    public static final int     CMD_GetMonomerRES                =    0x62;
    public static final int      CMD_GetMonomerCAP                =    0x63;
    public static final int      CMD_GetMonomerChargeCAP            =    0x64;
    public static final int      CMD_GetMonomerTMP                =    0x65;
    //-----------------------------------------------------------------------------
    //------------ 在线电压校准 ----------------------------------------------------
    public static final int     CMD_GetOnlineVolAdjParam        =    0x6A;
    public static final int     CMD_SetOnlineVolAdjParam        =    0x6B;
    //------------ 组端电压校准 ----------------------------------------------------
    public static final int     CMD_GetBattGroupVolAdjParam        =    0x6C;
    public static final int     CMD_SetBattGroupVolAdjParam        =    0x6D;
    //------------ 放电电流校准 ----------------------------------------------------
    public static final int     CMD_GetDischargeCurrAdjParam    =    0x6E;
    public static final int     CMD_SetDischargeCurrAdjParam    =    0x6F;
    //------------ 充电电流校准 ----------------------------------------------------
    public static final int     CMD_GetChargeCurrAdjParam        =    0x70;
    public static final int     CMD_SetChargeCurrAdjParam        =    0x71;
    //------------ 单体内阻校准 ----------------------------------------------------
    public static final int     CMD_GetBattResAdjParam            =   0x72;
    public static final int     CMD_SetBattResAdjParam            =    0x73;
    //------------ 单体电压偏移/斜率校准 --------------------------------------------
    public static final int     CMD_GetMonVolAdjParam            =    0x74;
    public static final int     CMD_SetMonVolAdjOffset            =    0x75;
    public static final int     CMD_SetMonVolAdjSlope            =    0x76;
    public static final int     CMD_ResetMonVolAdjParam            =    0x77;
    //-----------------------------------------------------------------------------
    //------------ 设置日期时间 ----------------------------------------------------
    public static final int     CMD_SetDateTime                    =   0x7A;
    //------------ 读取设置系统参数和告警参数 ---------------------------------------
    public static final int     CMD_GetSYSSetParam                =    0x80;
    public static final int     CMD_SetSYSSetParam                =    0x81;
    public static final int     CMD_GetAlarmParam                =    0x82;
    public static final int     CMD_SetAlarmParam                =    0x83;
    //------------------------------------------------------------------------------
    //------------ 测试类型 ---------------------------------------------------------
    public static final int        TestType_NULL                    =    0x00;
    public static final int        TestType_VOL                    =    0xF9;
    public static final int        TestType_MDISCHARGE                =    0xFA;
    public static final int        TestType_MCHARGE                =    0xFB;
    public static final int        TestType_Charge                    =    0xFC;
    public static final int        TestType_CAP                    =    0xFD;
    public static final int        TestType_RES                    =    0xFE;
    //------------------------------------------------------------------------------
    //------------ 电池状态 ---------------------------------------------------------
    public static final int        BattState_Float                    =    0x00;
    public static final int        BattState_Discharge                =    0x01;
    public static final int        BattState_Charge                =    0x02;
    //------------------------------------------------------------------------------
    //------------ 数据类型 ---------------------------------------------------------
    public static final int        DataType_Null                    =    0x00;
    public static final int        DataType_MonVol                    =    0x01;
    public static final int        DataType_MonCap                    =    0x02;
    public static final int        DataType_MonRes                    =    0x03;
    public static final int        DataType_Temp                    =    0x04;
    public static final int        DataType_GrpVol                    =    0x05;
    public static final int        DataType_Curr                    =    0x06;
    public static final int        DataType_MonTmp                    =    0x07;
    //------------------------------------------------------------------------------
    //------------------------------------------------------------------------------
    //------------ FBO返回状态 ---------------------------------------------------------
    public static final int        DataReturn_Successs                =    0x00;
    public static final int        DataReturn_Fail                    =    0x01;
    //------------ Android  读取命令 ---------------------------------------------------------------------
    public static final int     CMD_HEARTBEAT                      =   0X0A01;            //心跳包
    public static final int     CMD_EXITMACHINECONTROL            =     0X0A02;            //退出上位机控制
    public static final int     CMD_ENTERMACHINECONTROL            =     0X0A03;            //进入上位机控制
    public static final int     CMD_GETDISCHARGEPARAM            =   0X0A04;            //读取放电参数
    public static final int        CMD_SETDISCHARGEPARAM            =     0X0A05;            //设置放电参数
    public static final int     CMD_GETBATTDATA                 =     0X0A06;            //获取单体数据
    public static final int        CMD_GETFILELIST                    =     0X0A07;            //获取文件列表
    public static final int        CMD_GETFILE                        =    0X0A08;            //获取文件
    public static final int     CMD_SETCHARGEPARAM                =    0X0A09;            //设置充电参数
    public static final int        CMD_GETCHARGEPARAM                =    0X0A0A;            //读取充电参数
    public static final int        CMD_STARTDISCHARGE                =    0X0A0B;            //启动放电
    public static final int      CMD_PAUSEDISCHARGE                =   0X0A0C;            //放电暂停
    public static final int     CMD_GETDISCHARGEDATA            =    0X0A0D;            //获取放电数据
    public static final int        CMD_STARTCHARGE                    =     0X0A0E;            //启动充电
    public static final int     CMD_PAUSECHARGE                    =     0X0A0F;            //充电暂停
    public static final int        CMD_GETCHARGEDATA                =    0X0A10;            //获取充电数据
    public static final int        CMD_GETJIAOZHUNDATA                =     0X0A11;            //获取校准界面数据
    public static final int        CMD_JIAOZHUNPARAMS                =    0X0A12;            //校准各个参数
    public static final int        CMD_JIAOZHUNDISCHARGE            =    0X0A13;            //校准界面放电
    public static final int        CMD_JIAOZHUNCHARGE                =    0X0A14;            //校准界面充电
    public static final int     CMD_JIAOZHUNSTOP                =    0X0A15;            //校准界面停止
    public static final int        CMD_RETURNMAIN                    =    0X0A16;            //返回主界面
    public static final int     CMD_GETCYCLEPARAM                =    0X0A17;            //获取循环参数
    public static final int        CMD_SETCYCLEPARAM                =    0X0A18;            //设置循环参数
    public static final int        CMD_CREATENEWBATT                =    0X0A19;            //新建电池组
    public static final int     CMD_CHANGEBATT                    =    0X0A1A;            //切换电池组
    public static final int     CMD_DELETENOWBATT                =   0X0A1B;            //删除当前电池组
    public static final int        CMD_STOPDISCHARGE                =     0X0A1C;            //停止放电
    public static final int        CMD_STOPCHARGE                    =     0X0A1D;            //停止充电
    public static final int     WORKSTATE_Stopped               =  0;        //停止
    public static final int     WORKSTATE_Paused_Dischg           =  1;        //暂停放电
    public static final int     WORKSTATE_Discharging             =  2;        //正在放电
    public static final int     WORKSTATE_Paused_charge         =  3;        //暂停充电
    public static final int     WORKSTATE_Charging              =  4;        //正在充电
    public static final int     RETURN_SUCCESS                    = 0X00;        //操作成功
    public static final int     RETURN_ERRORLEN                    = 0X01;        //数据长度错误
    public static final int     RETURN_ERRORCRC                    = 0X02;        //CRC错误
    public static final int     RETURN_ERRORMODE                = 0X03;        //进入Android模式失败
    public static final int     RETURN_ERRORINDEX                = 0X04;        //索引错误
    public static final int     RETURN_ERRORTEST                = 0X05;        //正在测试错误
    public static byte changeIntToByte(int data)
    {
        return (byte)(data & 0xFF);
    }
    //------------------------------------------------------------------------------
    public static short changeIntToShort(int data)
    {
        return (short)(data & 0xFFFF);
    }
    //------------------------------------------------------------------------------
    public static byte changeShortToByte(short data)
    {
        return (byte)(data & 0xFF);
    }
    //------------------------------------------------------------------------------
    public static int changeByteToInt(byte data)
    {
        int tmp = data;
        return (tmp & 0xFF);
    }
    //------------------------------------------------------------------------------
    public static int changeShortToInt(short data)
    {
        int tmp = data;
        return (tmp & 0xFFFF);
    }
    //------------------------------------------------------------------------------
    public static double changeShortToDouble(short data)
    {
        int tmp = data & 0xFFFF;
        return (double)(tmp);
    }
    //------------------------------------------------------------------------------
    public static short changeDoubleToShort(double data)
    {
        int tmp = (int)data;
        return (short)(tmp & 0xFFFF);
    }
    //------------------------------------------------------------------------------
    //------------------------------------------------------------------------------
    public static double GetFDCurrent(double stdcap, int hourrate)
    {
        double res = 0.055;
        switch(hourrate)
        {
            case 1: res = 0.514; break;
            case 2: res = 0.306; break;
            case 3: res = 0.250; break;
            case 4: res = 0.200; break;
            case 5: res = 0.166; break;
            case 6: res = 0.146; break;
            case 7: res = 0.131; break;
            case 8: res = 0.118; break;
            case 9: res = 0.108; break;
            case 10: res = 0.100; break;
            case 20: res = 0.055; break;
            default: res = 0.055; break;
        }
        return (stdcap * res);
    }
    //------------------------------------------------------------------------------
    //------------------------------------------------------------------------------
    public static int GetHourRate(int stdah, int current)
    {
        int index = 0;
        int value[]={514, 306, 250, 200, 166, 146, 131, 118, 108, 100, 55};
        int res;
        res = (current*100)/(stdah/10);
        if(res>=514) return 1;
        else if(res<=55) return 20;
        else
        {
            for(index=0; index<10; index++)
            {
                if((res<=value[index]) && (res>value[index+1]))    break;
                else continue;
            }
            if((value[index]-res) < (res-value[index+1]))
            {
                return (index+1);
            }
            else
            {
                if(index+2 > 10) return (20);
                else return (index+2);
            }
        }
    }
    //------------------------------------------------------------------------------
    //------------------------------------------------------------------------------
    public static double N_TO_10H(int n_H)
    {
        switch(n_H)
        {
            case  1 : return(1/0.55);
            case  2 : return(1/0.61);
            case  3 : return(1/0.75);
            case  4 : return(1/0.79);
            case  5 : return(1/0.833);
            case  6 : return(1/0.876);
            case  7 : return(1/0.917);
            case  8 : return(1/0.944);
            case  9 : return(1/0.974);
            case  10: return(1/1);
            case  20: return(1/1.1);
        }
        return 1.0;
    }
    //-------------------------------------------------------------------------------
    /*
    //-------------------------------------------------------------------------------
    double GetMonomerCap(double STDAH, int HourRate, double SumAH, double MaxMonomerVol,
                        double MonomerVol, double MonomerVolType, int CapType)
    {
        if(MaxMonomerVol - MonomerVolType*0.9 == 0)
            return 0;
        if(SumAH < 0)
            SumAH *= (-1);
        double tmp_cap;
        tmp_cap = MonomerVol - MonomerVolType * 0.9;
        tmp_cap *= (STDAH - SumAH * N_TO_10H(HourRate));
        tmp_cap = tmp_cap/(MaxMonomerVol - MonomerVolType*0.9);
        if(tmp_cap < 0)
            tmp_cap = 0;
        if(CapType == CapType_Rest)
            return tmp_cap;
        else if(CapType == CapType_Sum)
            return (tmp_cap + SumAH * N_TO_10H(HourRate));
        else
            return ((tmp_cap + SumAH * N_TO_10H(HourRate))*100 / STDAH);
    }
    //----------------------------------------------------------------------------------
    */
}
/***************************************************************************************
 ******************************* end of file (FBS_ComBase)*******************************
 ***************************************************************************************/
platforms/android/app/src/main/java/com/util/FBS_ComBuf.java
New file
@@ -0,0 +1,68 @@
package com.util;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Random;
public class FBS_ComBuf
{
    FBS_Cmd m_CMD = new FBS_Cmd();
    public FBS_Cmd getFbsCmd()
    {
        return m_CMD;
    }
    public boolean putByteBuffer(final ByteBuffer bf)
    {
        if(false == m_CMD.putByteBuffer(bf))
            return false;
        return true;
    }
    public static ByteBuffer makeFbs9100CommBuf(int addr, int cmd, ByteBuffer bf)
    {
        FBS_Cmd m_CMD = new FBS_Cmd();
        ByteBuffer buffer = ByteBuffer.allocate(m_CMD.BYTE_LEN + bf.limit());
        buffer.order(ByteOrder.LITTLE_ENDIAN);
        m_CMD.makeCmd( cmd, bf.limit());
        buffer.put(m_CMD.getByteBuffer(bf));
        //buffer.put(bf);
        buffer.flip();
        return buffer;
    }
    public static ByteBuffer makeFbs9100CommBuf(int addr, int cmd, ByteBuffer bf, boolean aes_en)
    {
        System.err.println(bf.limit()+"$$$$$$$$$$");
        FBS_Cmd m_CMD = new FBS_Cmd();
        ByteBuffer buffer = ByteBuffer.allocate(m_CMD.BYTE_LEN + bf.limit() + 32);
        buffer.order(ByteOrder.LITTLE_ENDIAN);            //����ByteBuffer���ֽ���
        m_CMD.makeCmd(cmd, bf.limit());
        buffer.put(m_CMD.getByteBuffer(bf));
        //buffer.put(bf);
        if(true == aes_en) {
            Random rd = new Random();
            if(0 == (buffer.position()%Ecb_Aes.AES_BLOCK_SIZE)) {
                for(int n=0; n<(Ecb_Aes.AES_BLOCK_SIZE/4); n++) {
                    buffer.putInt(rd.nextInt());
                }
            } else {
                int cnt = Ecb_Aes.AES_BLOCK_SIZE - (buffer.position()%Ecb_Aes.AES_BLOCK_SIZE);
                for(int n=0; n<cnt; n++) {
                    buffer.put((byte) rd.nextInt());
                }
            }
        }
        buffer.flip();
        return buffer;
    }
}
/***************************************************************************************
****************************** end of file (FBS_ComBuf) ********************************
***************************************************************************************/
platforms/android/app/src/main/java/com/util/FBS_Crc16.java
New file
@@ -0,0 +1,69 @@
package com.util;
import java.nio.ByteBuffer;
public class FBS_Crc16
{
    private final static int CRC16Table[] =
            {
                    0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
                    0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
                    0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
                    0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
                    0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
                    0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
                    0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
                    0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
                    0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
                    0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
                    0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
                    0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
                    0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
                    0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
                    0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
                    0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
                    0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
                    0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
                    0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
                    0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
                    0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
                    0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
                    0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
                    0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
                    0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
                    0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
                    0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
                    0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
                    0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
                    0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
                    0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
                    0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
            };
    public static int CalCRC16(final ByteBuffer buf, int count)
    {
        ByteBuffer tmpbuf = buf;
        tmpbuf.position(0);
        ///int crc = 0xFFFF;
        int crc = 0x00;
        int tmp;
        for (int i=0; i<count; i++)
        {
            if(!buf.hasRemaining())
                break;
            tmp = crc;
            crc = CRC16Table[(int)((((tmp&0xFFFF) >> 8) ^ (tmpbuf.get())) & 0xFF)];
            crc = crc ^ ((tmp&0xFFFF) << 8);
            //crc = CRC16Table[(int)((tmp&0xFFFF)>>8) ^ tmpbuf.get()];
            //crc = crc ^ (tmp<<8);
        }
        return (crc & 0xFFFF);
    }
}
/***************************************************************************************
 ****************************** end of file (FBS_Crc16) *********************************
 ***************************************************************************************/