|
@@ -0,0 +1,642 @@
|
|
|
+package com.wdkl.tradition.service;
|
|
|
+
|
|
|
+import android.os.CountDownTimer;
|
|
|
+import android.text.TextUtils;
|
|
|
+import android.util.Log;
|
|
|
+
|
|
|
+import com.kongqw.serialportlibrary.Device;
|
|
|
+import com.kongqw.serialportlibrary.SerialPortFinder;
|
|
|
+import com.kongqw.serialportlibrary.SerialPortManager;
|
|
|
+import com.kongqw.serialportlibrary.listener.OnOpenSerialPortListener;
|
|
|
+import com.kongqw.serialportlibrary.listener.OnSerialPortDataListener;
|
|
|
+import com.wdkl.tradition.common.Constants;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Iterator;
|
|
|
+import java.util.List;
|
|
|
+import java.util.TimerTask;
|
|
|
+import java.util.concurrent.Executors;
|
|
|
+import java.util.concurrent.ScheduledExecutorService;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+public class SerialPortService implements OnOpenSerialPortListener {
|
|
|
+ private static final String TAG = SerialPortService.class.getSimpleName();
|
|
|
+
|
|
|
+ private volatile static SerialPortService serialPortService = null;
|
|
|
+
|
|
|
+ private SerialPortManager mSerialPortManager;
|
|
|
+ private Device device;
|
|
|
+ private Boolean portOpened = false;
|
|
|
+ private static SerialModel heartModel = null;
|
|
|
+
|
|
|
+
|
|
|
+ private IDebugInfoListner debugInfoListner;
|
|
|
+ private ISerialPortListener serialPortListener;
|
|
|
+
|
|
|
+ public Device getDevice() {
|
|
|
+ return device;
|
|
|
+ }
|
|
|
+
|
|
|
+ private SerialPortService() {
|
|
|
+ init();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static SerialPortService getInstance() {
|
|
|
+ if (serialPortService == null) {
|
|
|
+ synchronized (SerialPortService.class) {
|
|
|
+ if (serialPortService == null) {
|
|
|
+ serialPortService = new SerialPortService();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return serialPortService;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void init() {
|
|
|
+ SerialPortFinder serialPortFinder = new SerialPortFinder();
|
|
|
+ ArrayList<Device> devices = serialPortFinder.getDevices();
|
|
|
+ Device device = null;
|
|
|
+ for (Device device1 : devices) {
|
|
|
+ File file = device1.getFile();
|
|
|
+ boolean canRead = file.canRead();
|
|
|
+ boolean canWrite = file.canWrite();
|
|
|
+ //boolean canExecute = file.canExecute();
|
|
|
+ if (canRead && canWrite) {
|
|
|
+ device = device1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (null == device) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.device = device;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void reOpenSerialPort() {
|
|
|
+ init();
|
|
|
+ openSerialPort();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void openSerialPort() {
|
|
|
+ if (this.device == null) {
|
|
|
+ Log.d(TAG, "未找到设备");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ mSerialPortManager = new SerialPortManager();
|
|
|
+ // 打开串口
|
|
|
+ try {
|
|
|
+ boolean openSerialPort = mSerialPortManager
|
|
|
+ .setOnSerialPortDataListener(new OnSerialPortDataListener() {
|
|
|
+ @Override
|
|
|
+ public void onDataReceived(byte[] bytes) {
|
|
|
+ //接收的数据有多帧时有问题
|
|
|
+ byte[] buf = checkData(bytes);
|
|
|
+ if (buf.length < 8) {
|
|
|
+ //Log.d("wzl", "invalid data, return.");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //Log.d("wzl", "after check data, the new data = " + bytesToHexString(buf));
|
|
|
+ List<Byte> buffer = new ArrayList<>();
|
|
|
+ for(byte bt:buf){
|
|
|
+ buffer.add(bt);
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ handleReceived(buffer);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onDataSent(byte[] bytes) {
|
|
|
+ //Log.i(TAG, "onDataSent byte: " + Arrays.toString(bytes)+ " hex:"+bytesToHexString(bytes));
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .openSerialPort(this.device.getFile(), 115200);
|
|
|
+ if (openSerialPort) {
|
|
|
+ Log.d(TAG, "串口打开成功");
|
|
|
+ portOpened = true;
|
|
|
+ //发送心跳包建立连接
|
|
|
+ TimerTask timerTask = new TimerTask() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ sendSignal(getHeartModel());
|
|
|
+ }
|
|
|
+ };
|
|
|
+ ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
|
|
|
+ executor.scheduleAtFixedRate(timerTask,0,10*1000L, TimeUnit.MILLISECONDS);
|
|
|
+ Log.d(TAG, "============= 心跳定时任务设置完成 ==========");
|
|
|
+ } else {
|
|
|
+ Log.d(TAG, "串口打开失败");
|
|
|
+ portOpened = false;
|
|
|
+ }
|
|
|
+ } catch (Exception ex) {
|
|
|
+ ex.printStackTrace();
|
|
|
+ portOpened = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void closeSerialPort(){
|
|
|
+ if (null != mSerialPortManager && portOpened) {
|
|
|
+ mSerialPortManager.closeSerialPort();
|
|
|
+ mSerialPortManager = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private byte[] buffer = new byte[256];
|
|
|
+ private int writeIndex = 0;
|
|
|
+
|
|
|
+ private byte[] checkData(byte[] data) {
|
|
|
+ if (data.length < 8) {
|
|
|
+ if (data[0] == 0x2E) { //同步头
|
|
|
+ writeIndex = 0;
|
|
|
+ for (int i = 0; i < data.length; i++) {
|
|
|
+ buffer[writeIndex] = data[i];
|
|
|
+ writeIndex++;
|
|
|
+ }
|
|
|
+ //Log.d("wzl", "checkData: 11111111111-----writeIndex = " + writeIndex);
|
|
|
+ } else {
|
|
|
+ //Log.d("wzl", "checkData: 22222222222-----writeIndex = " + writeIndex);
|
|
|
+ if (writeIndex > 0) {
|
|
|
+ for (int j = 0; j < data.length; j++) {
|
|
|
+ buffer[writeIndex] = data[j];
|
|
|
+ writeIndex++;
|
|
|
+ }
|
|
|
+ int newSize = writeIndex;
|
|
|
+ //Log.d("wzl", "checkData: 3333333333-----writeIndex = " + writeIndex + ", newSize=" + newSize);
|
|
|
+ if (newSize >= 8) {
|
|
|
+ byte[] readBytes = new byte[newSize];
|
|
|
+ System.arraycopy(buffer, 0, readBytes, 0, newSize);
|
|
|
+ writeIndex = 0;
|
|
|
+ return readBytes;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setDebugInfoListner(IDebugInfoListner listner) {
|
|
|
+ debugInfoListner = listner;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setSerialPortListener(ISerialPortListener listener) {
|
|
|
+ serialPortListener = listener;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void handleReceived(List<Byte> bytePkg){
|
|
|
+ SerialModel serialModel = SerialModel.getSerialModel(bytePkg);
|
|
|
+ if (serialModel==null){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ SerialSignalTypeEnum serialSignalTypeEnum = SerialSignalTypeEnum.getEnum(serialModel.getDataType());
|
|
|
+ if (serialSignalTypeEnum == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Log.d(TAG," <<<<<<<<<<<<< 收到包: "+serialSignalTypeEnum.getDesc());
|
|
|
+
|
|
|
+ if (Constants.showLog && debugInfoListner != null && serialSignalTypeEnum != SerialSignalTypeEnum.MCU_MSG_VERSION_INFO) {
|
|
|
+ String log = serialSignalTypeEnum.getDesc() + ", uart addr: " + getUAddr(serialModel.getSlaveAddH(), serialModel.getSlaveAddL())
|
|
|
+ + ", data: " + bytesToHexString(serialModel.getData());
|
|
|
+ debugInfoListner.onDebugInfo(log);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (serialPortListener != null) {
|
|
|
+ serialPortListener.onSerialReceived(serialModel);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private SerialModel getHeartModel(){
|
|
|
+ if (heartModel == null){
|
|
|
+ heartModel = new SerialModel(
|
|
|
+ (byte) 0x00, (byte) 0x00,
|
|
|
+ SerialSignalTypeEnum.APP_MSG_CONNECT_CHK.getDataType(), (byte) 0x01
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return heartModel;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void sendSignal(SerialModel signal) {
|
|
|
+ SerialSignalTypeEnum serialSignalTypeEnum = SerialSignalTypeEnum.getEnum(signal.getDataType());
|
|
|
+ //if (serialSignalTypeEnum != SerialSignalTypeEnum.APP_MSG_CONNECT_CHK) {
|
|
|
+ Log.d(TAG, " >>>>>>>>>>>> 发送包: " + serialSignalTypeEnum.getDesc());
|
|
|
+ //}
|
|
|
+ if (mSerialPortManager != null) {
|
|
|
+ mSerialPortManager.sendBytes(signal.getSendBytes());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void sendSignal(byte[] sendContentBytes, String successMsg, String failedMsg) {
|
|
|
+ boolean sendBytes = mSerialPortManager.sendBytes(sendContentBytes);
|
|
|
+ //Log.i(TAG, "onSend: sendBytes = " + sendBytes);
|
|
|
+ }
|
|
|
+
|
|
|
+ //向MCU注册设备
|
|
|
+/* public void initMCUDeviceAddr(String uAddr){
|
|
|
+ byte[] slaveAdd = SerialPortService.hexToByteArray(uAddr);
|
|
|
+ SerialModel serialModel = new SerialModel(
|
|
|
+ (byte) 0x00, (byte) 0x00,
|
|
|
+ SerialSignalTypeEnum.APP_MSG_DEVICEMAC_INFO.getDataType(),
|
|
|
+ (byte)0x01,(byte)0x01,slaveAdd[0],slaveAdd[1]
|
|
|
+ );
|
|
|
+ sendSignal(serialModel);
|
|
|
+ Log.d(TAG,"向MCU注册设备,地址:"+uAddr);
|
|
|
+ }*/
|
|
|
+
|
|
|
+ private void initMCUDevice(String uAddr, int id, int count){
|
|
|
+ if (uAddr != null) {
|
|
|
+ byte num = (byte) (count & 0xff);
|
|
|
+ byte index = (byte) (id & 0xff);
|
|
|
+ byte[] slaveAddr = hexToByteArray(uAddr);
|
|
|
+ SerialModel serialModel = new SerialModel(
|
|
|
+ (byte) 0x00, (byte) 0x00,
|
|
|
+ SerialSignalTypeEnum.APP_MSG_DEVICEMAC_INFO.getDataType(),
|
|
|
+ num, /* 设备数 */
|
|
|
+ index, /* 设备序号 */
|
|
|
+ slaveAddr[0], slaveAddr[1] /* 设备地址 */
|
|
|
+ );
|
|
|
+ sendSignal(serialModel);
|
|
|
+ Log.d(TAG,"向MCU注册设备,地址:"+ uAddr);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //查询MCU版本号
|
|
|
+ public void checkMCUVersion(String uAddr) {
|
|
|
+ if (uAddr != null && !uAddr.isEmpty()) {
|
|
|
+ byte[] slaveAdd = SerialPortService.hexToByteArray(uAddr);
|
|
|
+ SerialModel serialModel = new SerialModel(
|
|
|
+ slaveAdd[0], slaveAdd[1],
|
|
|
+ SerialSignalTypeEnum.APP_MSG_INQUIRE_REQ.getDataType(),
|
|
|
+ (byte) 0x02
|
|
|
+ );
|
|
|
+ sendSignal(serialModel);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //查询分机状态
|
|
|
+ private CheckStatusCallback mCallback = null;
|
|
|
+ public interface CheckStatusCallback {
|
|
|
+ void onCheckCompleted(String uAddr, int status);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void checkSlaveStatus(String uAddr, CheckStatusCallback callback){
|
|
|
+ mCallback = callback;
|
|
|
+ checkSlaveStatus(uAddr);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void checkSlaveStatus(String uAddr){
|
|
|
+ if (uAddr != null && !uAddr.isEmpty()) {
|
|
|
+ byte[] slaveAdd = SerialPortService.hexToByteArray(uAddr);
|
|
|
+ SerialModel serialModel = new SerialModel(
|
|
|
+ slaveAdd[0], slaveAdd[1],
|
|
|
+ SerialSignalTypeEnum.APP_MSG_INQUIRE_REQ.getDataType(),
|
|
|
+ (byte) 0x01
|
|
|
+ );
|
|
|
+ sendSignal(serialModel);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public interface CallingCheckCallback {
|
|
|
+ void onCallingCheckComplete(String uAddr, int status);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void removeCallbacks() {
|
|
|
+ mCallback = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ //主机主动或回应呼叫
|
|
|
+ public void startCall(String addr) {
|
|
|
+ byte[] slaveAdd = SerialPortService.hexToByteArray(addr);
|
|
|
+ SerialModel serialModel = new SerialModel(
|
|
|
+ slaveAdd[0], slaveAdd[1],
|
|
|
+ SerialSignalTypeEnum.APP_MSG_CALL_IN_RES.getDataType(), (byte) 0x00
|
|
|
+ );
|
|
|
+ sendSignal(serialModel);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void stopCall(String addr){
|
|
|
+ byte[] slaveAdd = SerialPortService.hexToByteArray(addr);
|
|
|
+ SerialModel serialModel = new SerialModel(
|
|
|
+ slaveAdd[0],slaveAdd[1],
|
|
|
+ SerialSignalTypeEnum.APP_MSG_CALL_OFF_REQ.getDataType(), (byte) 0x00
|
|
|
+ );
|
|
|
+ sendSignal(serialModel);
|
|
|
+ }
|
|
|
+
|
|
|
+ //通话模式设置
|
|
|
+ public void setCallMode(int mode) {
|
|
|
+ SerialModel serialModel = new SerialModel(
|
|
|
+ (byte) 0x00, (byte) 0x00,
|
|
|
+ SerialSignalTypeEnum.APP_MSG_CALLMODE_SET.getDataType(),
|
|
|
+ (byte) (mode & 0xff)
|
|
|
+ );
|
|
|
+ sendSignal(serialModel);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 分机呼叫请求,门灯亮红灯
|
|
|
+ * 颜色值:G,R,B -- 0: 灯灭, 1: 常亮 2: 闪烁
|
|
|
+ */
|
|
|
+ public void sendDoorLedOnCmd(String addr) {
|
|
|
+ if (addr != null && !addr.isEmpty()) {
|
|
|
+ byte[] slaveAdd = hexToByteArray(addr);
|
|
|
+ SerialModel serialModel = new SerialModel(slaveAdd[0], slaveAdd[1],
|
|
|
+ SerialSignalTypeEnum.APP_MSG_DOORLED_SET.getDataType(),
|
|
|
+ (byte) 0x00, (byte) 0x01, (byte) 0x00);
|
|
|
+ sendSignal(serialModel);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void sendDoorLedOffCmd(String addr) {
|
|
|
+ if (addr != null && !addr.isEmpty()) {
|
|
|
+ byte[] slaveAdd = hexToByteArray(addr);
|
|
|
+ SerialModel serialModel = new SerialModel(slaveAdd[0], slaveAdd[1],
|
|
|
+ SerialSignalTypeEnum.APP_MSG_DOORLED_SET.getDataType(),
|
|
|
+ (byte) 0x00, (byte) 0x00, (byte) 0x00);
|
|
|
+ sendSignal(serialModel);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //通知MCU关闭紧急按钮呼叫
|
|
|
+ public void sendSOSOffCmd(String addr) {
|
|
|
+ if (addr != null && !addr.isEmpty()) {
|
|
|
+ byte[] slaveAdd = hexToByteArray(addr);
|
|
|
+ SerialModel serialModel = new SerialModel(slaveAdd[0], slaveAdd[1],
|
|
|
+ SerialSignalTypeEnum.APP_MSG_SOSOFF_REQ.getDataType(), (byte) 0x00);
|
|
|
+ sendSignal(serialModel);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //开始广播,固定发送[2E C0 FF FF 87 01 01 B8]
|
|
|
+ public void startBroadcast() {
|
|
|
+ SerialModel serialModel = new SerialModel((byte) 0xFF, (byte) 0xFF,
|
|
|
+ SerialSignalTypeEnum.APP_MSG_BROADCAST_REQ.getDataType(), (byte) 0x01);
|
|
|
+ sendSignal(serialModel);
|
|
|
+ }
|
|
|
+
|
|
|
+ //停止广播,固定发送[2E C0 FF FF 86 01 01 B9]
|
|
|
+ public void stopBroadcast() {
|
|
|
+ SerialModel serialModel = new SerialModel((byte) 0xFF, (byte) 0xFF,
|
|
|
+ SerialSignalTypeEnum.APP_MSG_CALL_OFF_REQ.getDataType(), (byte) 0x00);
|
|
|
+ sendSignal(serialModel);
|
|
|
+ }
|
|
|
+
|
|
|
+ //设置主机和分机音量
|
|
|
+ //分免提和手柄状态,总共8项,数值在0x00~0xff之间
|
|
|
+ public void setMCUVolumes(int[] volumes) {
|
|
|
+ //float rate = 255/100f;
|
|
|
+ //for (int i = 0; i < volumes.length; i++) {
|
|
|
+ // volumes[i] = (int) (volumes[i] * rate);
|
|
|
+ //}
|
|
|
+ SerialModel serialModel = new SerialModel(
|
|
|
+ (byte) 0x00, (byte) 0x00,
|
|
|
+ SerialSignalTypeEnum.APP_MSG_PHONEVOL_SET.getDataType(),
|
|
|
+ (byte) (volumes[0] & 0xff),
|
|
|
+ (byte) (volumes[1] & 0xff),
|
|
|
+ (byte) (volumes[2] & 0xff),
|
|
|
+ (byte) (volumes[3] & 0xff),
|
|
|
+ (byte) (volumes[4] & 0xff),
|
|
|
+ (byte) (volumes[5] & 0xff),
|
|
|
+ (byte) (volumes[6] & 0xff),
|
|
|
+ (byte) (volumes[7] & 0xff)
|
|
|
+ );
|
|
|
+ sendSignal(serialModel);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onSuccess(File file) {
|
|
|
+ Log.d(TAG, String.format("串口 [%s] 打开成功", file.getPath()));
|
|
|
+ portOpened = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onFail(File file, Status status) {
|
|
|
+ switch (status) {
|
|
|
+ case NO_READ_WRITE_PERMISSION:
|
|
|
+ Log.d(TAG, "没有读写权限");
|
|
|
+ break;
|
|
|
+ case OPEN_FAIL:
|
|
|
+ default:
|
|
|
+ Log.d(TAG, "串口打开失败");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ portOpened = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static byte getCheckSum(List<Byte> byteList){
|
|
|
+ byte[] beforeCheckSum = new byte[6+byteList.get(5).intValue()];
|
|
|
+ beforeCheckSum[0] = byteList.get(1); //slaveAddH
|
|
|
+ beforeCheckSum[1] = byteList.get(2); //slaveAddL
|
|
|
+ beforeCheckSum[2] = byteList.get(3); //hostAdd
|
|
|
+ beforeCheckSum[3] = byteList.get(4); //dataType
|
|
|
+ beforeCheckSum[4] = byteList.get(5); //dataLength
|
|
|
+ for (int i = 0; i < byteList.get(5).intValue(); i++) {
|
|
|
+ beforeCheckSum[6+i] = byteList.get(6+i);
|
|
|
+ }
|
|
|
+
|
|
|
+ //cal checkSum
|
|
|
+ byte checkSum = 0;
|
|
|
+ for(byte bt:beforeCheckSum){
|
|
|
+ checkSum+=bt;
|
|
|
+ }
|
|
|
+ checkSum^=0xff;
|
|
|
+ return checkSum;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Boolean getPortOpened() {
|
|
|
+ return portOpened;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String getUAddr(byte slaveAddH, byte slaveAddL){
|
|
|
+ byte[] slaveAdd = {slaveAddH, slaveAddL};
|
|
|
+ return bytesToHexString(slaveAdd);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Hex字符串转byte
|
|
|
+ *
|
|
|
+ * @param inHex 待转换的Hex字符串
|
|
|
+ * @return 转换后的byte
|
|
|
+ */
|
|
|
+ public static byte hexToByte(String inHex) {
|
|
|
+ return (byte) Integer.parseInt(inHex, 16);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * hex字符串转byte数组
|
|
|
+ *
|
|
|
+ * @param inHex 待转换的Hex字符串
|
|
|
+ * @return 转换后的byte数组结果
|
|
|
+ */
|
|
|
+ public static byte[] hexToByteArray(String inHex) {
|
|
|
+ int hexlen = inHex.length();
|
|
|
+ byte[] result;
|
|
|
+ if (hexlen % 2 == 1) {
|
|
|
+ // 奇数
|
|
|
+ hexlen++;
|
|
|
+ result = new byte[(hexlen / 2)];
|
|
|
+ inHex = "0" + inHex;
|
|
|
+ } else {
|
|
|
+ // 偶数
|
|
|
+ result = new byte[(hexlen / 2)];
|
|
|
+ }
|
|
|
+ int j = 0;
|
|
|
+ for (int i = 0; i < hexlen; i += 2) {
|
|
|
+ result[j] = hexToByte(inHex.substring(i, i + 2));
|
|
|
+ j++;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 数组转换成十六进制字符串
|
|
|
+ *
|
|
|
+ * @param bArray
|
|
|
+ * @return HexString
|
|
|
+ */
|
|
|
+ public static final String bytesToHexString(byte[] bArray) {
|
|
|
+ StringBuffer sb = new StringBuffer(bArray.length);
|
|
|
+ String sTemp;
|
|
|
+ for (int i = 0; i < bArray.length; i++) {
|
|
|
+ sTemp = Integer.toHexString(0xFF & bArray[i]);
|
|
|
+ if (sTemp.length() < 2)
|
|
|
+ sb.append(0);
|
|
|
+ sb.append(sTemp.toUpperCase());
|
|
|
+ }
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static byte[] buildSignal(byte data){
|
|
|
+ byte head = (byte)0x2E;
|
|
|
+ // 2E0000C03201000C
|
|
|
+ byte[] signalBody = {(byte)0x00,(byte)0x00,(byte)0xC0,(byte)0x32,(byte)0x01,data};
|
|
|
+ byte checkSum = 0;
|
|
|
+ for(byte bt:signalBody){
|
|
|
+ checkSum+=bt;
|
|
|
+ }
|
|
|
+ checkSum^=0xff;
|
|
|
+ byte[] signal = new byte[8];
|
|
|
+ signal[0]=head;
|
|
|
+ for (int i = 0; i < signalBody.length; i++) {
|
|
|
+ signal[i+1]=signalBody[i];
|
|
|
+ }
|
|
|
+ signal[7]=checkSum;
|
|
|
+ return signal;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ byte[] signal = {(byte)0x22,(byte)0x4E};
|
|
|
+ byte[] signal1 = buildSignal((byte)0x00);
|
|
|
+ byte[] signal2 = buildSignal((byte)0x24);
|
|
|
+
|
|
|
+ byte[] temp = byteMerger(signal,signal1);
|
|
|
+ byte[] si = byteMerger(temp,signal2);
|
|
|
+
|
|
|
+ List<Byte> ttt = new ArrayList<>();
|
|
|
+ for(byte bt:si){
|
|
|
+ ttt.add(bt);
|
|
|
+ }
|
|
|
+ System.out.println(" >>> "+ttt);
|
|
|
+
|
|
|
+ List<Byte> x = new ArrayList<>();
|
|
|
+
|
|
|
+ for (int i = 0; i < si.length; i++) {
|
|
|
+ x.add(si[i]);
|
|
|
+ if (i==4){
|
|
|
+ dataReceived(listTobyte(x));
|
|
|
+ x=new ArrayList<>();
|
|
|
+ }
|
|
|
+ if (i==12){
|
|
|
+ dataReceived(listTobyte(x));
|
|
|
+ x=new ArrayList<>();
|
|
|
+ }
|
|
|
+ if (i==si.length-1){
|
|
|
+ dataReceived(listTobyte(x));
|
|
|
+ x=new ArrayList<>();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static byte[] byteMerger(byte[] bt1, byte[] bt2){
|
|
|
+ byte[] bt3 = new byte[bt1.length+bt2.length];
|
|
|
+ int i=0;
|
|
|
+ for(byte bt: bt1){
|
|
|
+ bt3[i]=bt;
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+
|
|
|
+ for(byte bt: bt2){
|
|
|
+ bt3[i]=bt;
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ return bt3;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static byte[] listTobyte(List<Byte> list) {
|
|
|
+ if (list == null || list.size() < 0)
|
|
|
+ return null;
|
|
|
+ byte[] bytes = new byte[list.size()];
|
|
|
+ int i = 0;
|
|
|
+ Iterator<Byte> iterator = list.iterator();
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ bytes[i] = iterator.next();
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ return bytes;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ static List<Byte> buffer1 = new ArrayList<>();
|
|
|
+ public static void dataReceived(byte[] bytes) {
|
|
|
+
|
|
|
+ for (int i = 0; i < bytes.length; i++) {
|
|
|
+ buffer1.add(bytes[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.println(" --- "+buffer1);
|
|
|
+ System.out.println("长度当前:"+buffer1.size());
|
|
|
+
|
|
|
+ //8位以上并且包含起始标识可能是个整包
|
|
|
+ if (buffer1.size()>=8 && buffer1.contains((byte)0x2E)){
|
|
|
+ int index= buffer1.indexOf((byte)0x2E);
|
|
|
+ System.out.println("有起始:"+index);
|
|
|
+
|
|
|
+ //是否有数据长度位
|
|
|
+ if (buffer1.size()-index>=6){
|
|
|
+ int dataLen = buffer1.get(index+(6-1)); //下标由0开始,减1
|
|
|
+ //有一个完整的包
|
|
|
+ if (buffer1.size()-index>=(6+dataLen+1)){
|
|
|
+ System.out.println("进入核验");
|
|
|
+ //获取的核验位
|
|
|
+ byte receivedCheckSum = buffer1.get(index+(6-1)+dataLen+1); //下标由0开始,减1
|
|
|
+ //计算检验位,由第2位至(末位-1)得到
|
|
|
+ List<Byte> forCheckSum = buffer1.subList(index,index+(6-1)+dataLen+1);
|
|
|
+ byte calculateCheckSum = getCheckSum(forCheckSum);
|
|
|
+ System.out.println("核验包:"+forCheckSum);
|
|
|
+ System.out.println("rcs:"+receivedCheckSum+" --- ccs:"+calculateCheckSum);
|
|
|
+ if (receivedCheckSum == calculateCheckSum){
|
|
|
+ List<Byte> pkgSignal = buffer1.subList(index,index+(6-1)+dataLen+1+1);
|
|
|
+
|
|
|
+ System.out.println("整包:"+pkgSignal.toString());
|
|
|
+
|
|
|
+ //重置buffer
|
|
|
+ List<Byte> afterBytes = buffer1.subList(index+(6-1)+dataLen+1+1,buffer1.size());
|
|
|
+ buffer1 = afterBytes;
|
|
|
+
|
|
|
+ System.out.println(""+buffer1);
|
|
|
+ System.out.println("长度当前:"+buffer1.size());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ System.out.println("未包含0x2E");
|
|
|
+ }
|
|
|
+ System.out.println(" ");
|
|
|
+ }
|
|
|
+}
|