|
@@ -0,0 +1,351 @@
|
|
|
+<template>
|
|
|
+ <div id="firmwareContainer">
|
|
|
+ <van-button @click="ConnectBrain">连接</van-button>
|
|
|
+ <p>脑环名称:{{ brain_sn }}</p>
|
|
|
+ <p v-html="result"></p>
|
|
|
+ <van-button @click="downloadUpateFile">下载更新文件</van-button>
|
|
|
+ <van-button @click="readUpdateFile">读取文件</van-button>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+import {getDeviceBySn} from "../../../requests/game";
|
|
|
+import game_store from "@/store/game";
|
|
|
+
|
|
|
+var $this;
|
|
|
+var FileSystemManager = wx.getFileSystemManager();
|
|
|
+export default {
|
|
|
+ name: "firmwareContainer",
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ brain_sn: "",
|
|
|
+ result: "",
|
|
|
+ updateImageSavePath: "",
|
|
|
+ software_version: "",
|
|
|
+ model: "",
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ /**
|
|
|
+ * 扫码连接设备
|
|
|
+ * @constructor
|
|
|
+ */
|
|
|
+ ConnectBrain() {
|
|
|
+ wx.scanCode({
|
|
|
+ onlyFromCamera: true,
|
|
|
+ scanType: ["barCode", "qrCode"],
|
|
|
+ success: (res) => {
|
|
|
+ let $data = res;
|
|
|
+ if ($data.result) {
|
|
|
+ let url = decodeURIComponent($data.result);
|
|
|
+ let $code = "";
|
|
|
+
|
|
|
+ //二维码
|
|
|
+ if (res.scanType == "QR_CODE") {
|
|
|
+ if (url.indexOf("AI") != -1) {
|
|
|
+ $code = url.substr(url.indexOf("AI"));
|
|
|
+ } else if (url.toUpperCase().indexOf("JELLYFISH")) {
|
|
|
+ $code = url.substr(url.toUpperCase().indexOf("JELLYFISH"));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //一维码
|
|
|
+ $code = res.result.toUpperCase();
|
|
|
+ }
|
|
|
+ console.log($code)
|
|
|
+ // 判断新的标识值
|
|
|
+ $this.brain_sn = $code;
|
|
|
+ $this.AddContent(`脑环:${$code}`)
|
|
|
+ //打开蓝牙设备
|
|
|
+ wx.getSystemInfo({
|
|
|
+ success(res) {
|
|
|
+ // 判断ios 和 安卓
|
|
|
+ if (res.platform == "ios") {
|
|
|
+ wx.openBluetoothAdapter({
|
|
|
+ //判断主机模式蓝牙是否打开
|
|
|
+ mode: "central",
|
|
|
+ success(res) {
|
|
|
+ //判断已经打开连接了
|
|
|
+ if (res["errMsg"] == "openBluetoothAdapter:ok") {
|
|
|
+ // $this.startBluetoothDevicesDiscovery();
|
|
|
+ wx.openBluetoothAdapter({
|
|
|
+ //判断从机模式蓝牙是否打开
|
|
|
+ mode: "peripheral",
|
|
|
+ success(res) {
|
|
|
+ if (res["errMsg"] == "openBluetoothAdapter:ok") {
|
|
|
+ $this.startBluetoothDevicesDiscovery();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fail(err) {
|
|
|
+ let $msg =
|
|
|
+ $this.$bluetooth.GetopenBluetoothAdapterError(
|
|
|
+ err["errCode"]
|
|
|
+ );
|
|
|
+ setTimeout(() => {
|
|
|
+ Toast.fail({
|
|
|
+ message: $msg,
|
|
|
+ });
|
|
|
+ }, 3000);
|
|
|
+ },
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fail(err) {
|
|
|
+ let $msg = $this.$bluetooth.GetopenBluetoothAdapterError(
|
|
|
+ err["errCode"]
|
|
|
+ );
|
|
|
+ setTimeout(() => {
|
|
|
+ Toast.fail({
|
|
|
+ message: $msg,
|
|
|
+ });
|
|
|
+ }, 3000);
|
|
|
+ },
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ // 安卓手机
|
|
|
+ wx.openBluetoothAdapter({
|
|
|
+ mode: "peripheral",
|
|
|
+ success(res) {
|
|
|
+ //判断已经打开连接了
|
|
|
+ if (res["errMsg"] == "openBluetoothAdapter:ok") {
|
|
|
+ $this.startBluetoothDevicesDiscovery();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fail(err) {
|
|
|
+ let $msg = $this.$bluetooth.GetopenBluetoothAdapterError(
|
|
|
+ err["errCode"]
|
|
|
+ );
|
|
|
+ setTimeout(() => {
|
|
|
+ Toast.fail({
|
|
|
+ message: $msg,
|
|
|
+ });
|
|
|
+ }, 3000);
|
|
|
+ },
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fail(res) {
|
|
|
+ console.log(res);
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 开始蓝牙被发现
|
|
|
+ */
|
|
|
+ startBluetoothDevicesDiscovery() {
|
|
|
+ wx.startBluetoothDevicesDiscovery({
|
|
|
+ allowDuplicatesKey: true,
|
|
|
+ success: (res) => {
|
|
|
+ //2021年10月21日15:07:57 通过sn 返回deviceId
|
|
|
+ getDeviceBySn($this.code).then((res) => {
|
|
|
+ let $data = res.data;
|
|
|
+ console.log($data.code);
|
|
|
+ $data = $data.data;
|
|
|
+ wx.getSystemInfo({
|
|
|
+ success(res) {
|
|
|
+ // 判断ios 和 安卓
|
|
|
+ if (res.platform == "ios") {
|
|
|
+ $this.onBluetoothDeviceFound();
|
|
|
+ } else {
|
|
|
+ if ($data.device_id) {
|
|
|
+ console.log("finded");
|
|
|
+ $this.device_finded = true;
|
|
|
+ $this.createBLEConnection($data.device_id);
|
|
|
+ } else {
|
|
|
+ $this.device_finded = false;
|
|
|
+ console.log("unfinded");
|
|
|
+ $this.onBluetoothDeviceFound();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ fail(err) {
|
|
|
+ $this.change_device_status(3);
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ onBluetoothDeviceFound() {
|
|
|
+ try {
|
|
|
+ wx.onBluetoothDeviceFound((res) => {
|
|
|
+ res.devices.forEach((device) => {
|
|
|
+ if (!device.name && !device.localName) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (device.localName && device.localName != "") {
|
|
|
+ device.name = device.localName;
|
|
|
+ }
|
|
|
+ if (device["name"].toUpperCase() == $this.brain_sn) {
|
|
|
+ wx.stopBluetoothDevicesDiscovery();
|
|
|
+ console.log("搜索设备", device);
|
|
|
+ $this.createBLEConnection(device.deviceId);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ } catch (e) {
|
|
|
+ console.log("打开蓝牙error", e);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 连接低功耗蓝牙设备
|
|
|
+ * @param deviceId
|
|
|
+ */
|
|
|
+ createBLEConnection(deviceId) {
|
|
|
+ wx.createBLEConnection({
|
|
|
+ deviceId: deviceId,
|
|
|
+ success: (res) => {
|
|
|
+
|
|
|
+ // 设置mtu单位大小
|
|
|
+ wx.setBLEMTU({
|
|
|
+ deviceId,
|
|
|
+ mtu: 250,
|
|
|
+ success(res) {
|
|
|
+ console.log("设置mtu成功", JSON.stringify(res));
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ $this.$bluetooth.getBLEDeviceServices(deviceId);
|
|
|
+ let $checkServices = setInterval(() => {
|
|
|
+ let $serviceId = game_store.getters.getServiceId();
|
|
|
+ if ($serviceId) {
|
|
|
+ clearInterval($checkServices);
|
|
|
+ $this.$bluetooth.openNotify($this);
|
|
|
+ $this.$bluetooth.watchingDevice($this);
|
|
|
+ $this.$bluetooth.watch_bluetooth_status($this);
|
|
|
+ //读取信息逐个写入
|
|
|
+ if (!$this.device_finded) {
|
|
|
+ setTimeout(() => {
|
|
|
+ $this.$bluetooth.SendOrder("02");
|
|
|
+ }, 3000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, 1500);
|
|
|
+ console.log("连接成功")
|
|
|
+ $this.AddContent("连接成功");
|
|
|
+ },
|
|
|
+ fail(err) {
|
|
|
+ console.log(err);
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 下载更新文件
|
|
|
+ */
|
|
|
+ downloadUpateFile() {
|
|
|
+ wx.downloadFile({
|
|
|
+ url: 'https://vs.shuimuai.com/ble/update.img', //仅为示例,并非真实的资源
|
|
|
+ success(res) {
|
|
|
+ // 只要服务器有响应数据,就会把响应内容写入文件并进入 success 回调,业务需要自行判断是否下载到了想要的内容
|
|
|
+ if (res.statusCode === 200) {
|
|
|
+ $this.AddContent("下载成功")
|
|
|
+ console.log(res)
|
|
|
+ //将临时文件保存到用户文件路径下
|
|
|
+ FileSystemManager.saveFile({
|
|
|
+ tempFilePath: res.tempFilePath,
|
|
|
+ filePath: `${wx.env.USER_DATA_PATH}/update.img`,
|
|
|
+ success(res) {
|
|
|
+ $this.updateImageSavePath = res.savedFilePath
|
|
|
+ $this.AddContent(`保存地址:${res.savedFilePath}`)
|
|
|
+ }, fail(err) {
|
|
|
+ console.log(err)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ AddContent(content) {
|
|
|
+ $this.result += `<p>${content}</p>`
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 读取更新文件
|
|
|
+ */
|
|
|
+ readUpdateFile() {
|
|
|
+ FileSystemManager.readFile({
|
|
|
+ filePath: $this.updateImageSavePath,
|
|
|
+ success(res) {
|
|
|
+ $this.AddContent("读取文件成功")
|
|
|
+ let buffer_len = new Uint8Array(res.data).length
|
|
|
+ let $file_dec_index = 0;
|
|
|
+ for (let i = 0; i < buffer_len; i += 16) {
|
|
|
+ let buffer = new Uint8Array(res.data, i, 16);
|
|
|
+ console.log(buffer)
|
|
|
+ if (i == 0) {
|
|
|
+ //读取第一行信息 并返回 文件解密下标
|
|
|
+ $file_dec_index = $this.getUpdateHeader0(buffer)
|
|
|
+ }
|
|
|
+ if (i == 1*16) {
|
|
|
+ for (let j = 0; j < buffer.length; j++) {
|
|
|
+ $this.software_version += String.fromCharCode(buffer[j])
|
|
|
+ }
|
|
|
+ $this.AddContent(`软件版本:${$this.software_version}`)
|
|
|
+ }
|
|
|
+ if (i == 2*16) {
|
|
|
+ for (let j = 0; j < buffer.length; j++) {
|
|
|
+ $this.model += String.fromCharCode(buffer[j])
|
|
|
+ }
|
|
|
+ $this.AddContent(`软件版本:${$this.model}`)
|
|
|
+ }
|
|
|
+ if(i==5*16){
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fail(err) {
|
|
|
+ console.log(err)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 获取第一行头部信息
|
|
|
+ * @param buffer 数据包
|
|
|
+ * @returns {number} 返回需要解密的位置信息
|
|
|
+ */
|
|
|
+ getUpdateHeader0(buffer) {
|
|
|
+ //验证升级标志
|
|
|
+ let update_tag = [88, 48, 57, 57]
|
|
|
+ let update_tag_count = update_tag.length
|
|
|
+ for (let i = 0; i < update_tag.length; i++) {
|
|
|
+ let _buffer = buffer[i].toString(16);
|
|
|
+ //验证升级标志
|
|
|
+ if (_buffer == update_tag[i]) {
|
|
|
+ update_tag_count -= 1;
|
|
|
+ if (update_tag_count == 0) {
|
|
|
+ $this.AddContent("验证升级标志成功")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取payload长度
|
|
|
+ let payload_len = ""
|
|
|
+ for (let i = 7; i > 3; i--) {
|
|
|
+ let _buffer = buffer[i].toString(16);
|
|
|
+ //验证升级标志
|
|
|
+ payload_len += `${_buffer}`;
|
|
|
+ }
|
|
|
+ payload_len = parseInt(payload_len, 16);
|
|
|
+ $this.AddContent(`payload长度:${payload_len}`)
|
|
|
+
|
|
|
+ //获取升级的offset
|
|
|
+ let update_offset = 0
|
|
|
+ for (let i = 15; i > 11; i--) {
|
|
|
+ let _buffer = buffer[i].toString(16);
|
|
|
+ //验证升级标志
|
|
|
+ update_offset += parseInt(_buffer);
|
|
|
+ }
|
|
|
+ $this.AddContent(`offset:${update_offset}`)
|
|
|
+
|
|
|
+ //文件总长度
|
|
|
+ let file_total_size = payload_len + parseInt(update_offset, 16)
|
|
|
+ $this.AddContent(`文件总长度:${file_total_size}`)
|
|
|
+ return update_offset;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ $this = this;
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|