From 32d03eaa865410f260f07f74428a166318512c87 Mon Sep 17 00:00:00 2001 From: DXL <64101226@qq.com> Date: Thu, 27 Aug 2020 12:23:49 +0800 Subject: [PATCH] Create BleCMDControl.java --- appmain/devices/BleCMDControl.java | 142 +++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 appmain/devices/BleCMDControl.java diff --git a/appmain/devices/BleCMDControl.java b/appmain/devices/BleCMDControl.java new file mode 100644 index 0000000..d4a00f9 --- /dev/null +++ b/appmain/devices/BleCMDControl.java @@ -0,0 +1,142 @@ +package com.proxgrind.devices; + +import com.proxgrind.chameleon.javabean.DeviceInfo; +import com.proxgrind.chameleon.packets.DataPackets; +import com.proxgrind.chameleon.utils.system.LogUtils; +import com.proxgrind.chameleon.utils.tools.HexUtil; + +import java.io.IOException; +import java.util.Arrays; + +/* + * 同步任务! + * 将会给对象上锁! + * */ +public class BleCMDControl { + /** + * 命令定义区域,我们需要进行命令包标志的定义! + */ + private static final int BLE_INFO = 0X69; + + private static final BleSerialControl control = BleSerialControl.get(); + private static final int BLE_INFO_PACKET_SIZE_MAX_MINI = 77; + private static final int BLE_INFO_PACKET_SIZE_MAX_TINY = 25; + private static final int TRANSFER_TIMEOUT = 2000; + private static final int REVEICE_TIMEOUT = TRANSFER_TIMEOUT; + + public static DeviceInfo getBLEInfo() { + DeviceInfo info = new DeviceInfo(); + // 谨记上锁! + synchronized (control) { + if (control.isDeviceConnected()) { + try { + if (isChameleonMini()) { + getInfoFromMini(info); + } else { + getInfoFromTiny(info); + } + } catch (IOException e) { + e.printStackTrace(); + } + } else { + LogUtils.d("设备未连接,可能通讯是USB"); + } + return info; + } + } + + public static boolean isChameleonMini() { + return !control.isCtrlCharacteristicExists(); + } + + private static void getInfoFromMini(DeviceInfo info) throws IOException { + control.setPushDataToBuffer(false); + // 打包一个命令! + byte[] infoCMD = DataPackets.getData(BLE_INFO); + control.write(infoCMD, 0, infoCMD.length, TRANSFER_TIMEOUT); + byte[] recvs = new byte[BLE_INFO_PACKET_SIZE_MAX_MINI]; + if (control.read(recvs, 0, 0, REVEICE_TIMEOUT) >= BLE_INFO_PACKET_SIZE_MAX_MINI) { + // 主版本号 + info.setMainVersion(recvs[0]); + // 次版本号 + info.setMinorVersion(recvs[1]); + // 版本特性 + info.setVersionFlag(HexUtil.byteArrayToInt(new byte[]{recvs[5], recvs[4], recvs[3], recvs[2]})); + // 版本字符串(BLE) + info.setBleVersion(new String(Arrays.copyOfRange(recvs, 6, 37))); + // BLE电池电压! + info.setBatteryVoltage(HexUtil.byteArrayToInt(new byte[]{recvs[41], recvs[40], recvs[39], recvs[38]})); + // BLE电池百分比! + info.setBatteryPercent(recvs[42]); + // AVR相关参数! + info.setAvrMainVersion(recvs[43]); + info.setAvrMinorVersion(recvs[44]); + info.setAvrVersion(new String(Arrays.copyOfRange(recvs, 44, 74))); + } else { + LogUtils.d("接收到的长度字节不够!"); + } + control.setPushDataToBuffer(true); + } + + private static void getInfoFromTiny(DeviceInfo info) throws IOException { + LogUtils.d("请求Tiny的信息"); + control.setPushDataToBuffer(false); + byte[] infoCMD = new byte[]{(byte) 0XA5, 0X69, 0X00, 0X00}; + // Tiny分离出来了一个控制点特征单独用来进行UART之外的操作! + // 因此我们需要往Tiny的控制特征写,而不是往标准的UART写接口写。 + control.write(infoCMD, 0, infoCMD.length, TRANSFER_TIMEOUT, BleSerialControl.CTRL_CHARACT_UUID); + byte[] recvs = new byte[1024]; + if (control.read(recvs, 0, 0, REVEICE_TIMEOUT) >= BLE_INFO_PACKET_SIZE_MAX_TINY) { + // BLE电池电压! + info.setBatteryVoltage(HexUtil.toIntFrom2Byte(new byte[]{recvs[1], recvs[0]})); + // BLE电池百分比! + info.setBatteryPercent(recvs[2]); + // BLE版本号 + info.setBleVersion(new String(Arrays.copyOfRange(recvs, 3, 18))); + } else { + LogUtils.d("接收到的长度字节不够!"); + } + control.setPushDataToBuffer(true); + } + + public static void openAirplaneMode() { + new Thread(new Runnable() { + @Override + public void run() { + byte[] infoCMD = new byte[]{(byte) 0XA5, 0X6B, 0X00, 0X00}; + try { + control.write(infoCMD, 0, infoCMD.length, TRANSFER_TIMEOUT, BleSerialControl.CTRL_CHARACT_UUID); + } catch (IOException e) { + e.printStackTrace(); + } + } + }).start(); + } + + /** + * 进行数据的传输与应答帧的接收 + */ + public static byte[] tranRecv(int cmd, byte[] data, int timeout) { + BleSerialControl control = BleSerialControl.get(); + if (!control.isDeviceConnected()) return null; + // 关闭缓冲区转发 + control.setPushDataToBuffer(false); + // 拼包并且发送数据! + byte[] sendPack = new DataPackets(cmd, data).getData(); + byte[] ret = new byte[BleSerialControl.MTU]; + try { + control.write(sendPack, 0, sendPack.length, timeout); + int status = control.read(ret, 0, 0, timeout); + if (status == -1) { + //超时了,我们返回空的字节组表示超时 + return new byte[0]; + } + } catch (IOException e) { + e.printStackTrace(); + return null; + } + // 回复缓冲区转发 + control.setPushDataToBuffer(true); + return ret; + } +}