import * as t from "./tools" const app = getApp(); const WXAPI = require('../request') /* import { HTTP } from "../server"; */ /** * 蓝牙工具类 * 封装小程序蓝牙流程方法 * 处理事件通信 */ class BLEHandler { constructor(blename, emitter) { this.blename = blename //厂家自定义的蓝牙设备名称 this.emitter = emitter // if(manufactureId==201){ // this.readCharacteristicId = "0000FFF0-0000-1000-8000-00805F9B34FB"; //能从硬件返回的信息中自动提取 // this.writeCharacteristicId = "0000FFF2-0000-1000-8000-00805F9B34FB"; //能从硬件返回的信息中自动提取 // this.notifyCharacteristicId = "0000FFF1-0000-1000-8000-00805F9B34FB"; //能从硬件返回的信息中自动提取 // this.deviceId = ""; //蓝牙Mac地址 // this.serviceId = "0000FFF3-0000-1000-8000-00805F9B34FB";//具体的serviceId要自己根据硬件提供设置。 // }else{ this.readCharacteristicId = ""; //能从硬件返回的信息中自动提取 this.writeCharacteristicId = "00002af1-0000-1000-8000-00805f9b34fb"; //能从硬件返回的信息中自动提取 this.notifyCharacteristicId = "00002af0-0000-1000-8000-00805f9b34fb"; //能从硬件返回的信息中自动提取 this.deviceId = ""; //蓝牙Mac地址 this.serviceId = "000018f0-0000-1000-8000-00805f9b34fb"; //具体的serviceId要自己根据硬件提供设置。 // } this.receivePacket = []; this.recPktLength = 0; this.recPktOffset = 0; } async openAdapter() { let [err, res] = await t._openAdapter.call(this); if (err != null) { this.emitter.emit("channel", { type: "connect", data: "未打开适配器" }) return false; } return true } async startSearch() { let [err, res] = await t._startSearch.call(this); if (err != null) { return; } this.emitter.emit("channel", { type: "connect", data: "正在连接中..." }) } async onBluetoothFound() { let [err, res] = await t._onBluetoothFound.call(this); if (err != null) { this.emitter.emit("channel", { type: "connect", data: "未找到设备" }) return false; } return true } async getBluetoothDevices() { let [err, res] = await t._getBluetoothDevices.call(this); if (err != null) { this.emitter.emit("channel", { type: "connect", data: "未找到设备" }) return false; } return true } async stopSearchBluetooth() { let [err, res] = await t._stopSearchBluetooth.call(this); if (err != null) { return; } } async connectBlue() { let [err, res] = await t._connectBlue.call(this); if (err != null) { return; } } async setBLEMTU() { let [err, res] = await t._setBLEMTU.call(this); if (err != null) { return; } } async getBLEServices() { let [err, res] = await t._getBLEServices.call(this); if (err != null) { return; } } async getCharacteristics() { let [err, res] = await t._getCharacteristics.call(this); if (err != null) { this.emitter.emit("channel", { type: "connect", data: "无法订阅特征值" }) // 取消连接 this.closeBLEConnection() this.closeBLEAdapter() wx.setStorageSync("bluestatus", ""); return false; } this.emitter.emit("channel", { type: "connect", data: "蓝牙已连接" }) wx.setStorageSync("bluestatus", "on"); return true } async notifyBLECharacteristicValueChange() { let [err, res] = await t._notifyBLECharacteristicValueChange.call(this); if (err != null) { return; } } async closeBLEConnection() { let [err, res] = await t._closeBLEConnection.call(this); if (err != null) { return; } } async closeBLEAdapter() { let [err, res] = await t._closeBLEAdapter.call(this); if (err != null) { return; } } async sentOrder(cmd, payload,timestamp, callback) { let data = t._sentOrder(cmd, payload,timestamp) console.log("-- 发送数据:", data) let arrayBuffer = new Uint8Array(data).buffer; let [err, res] = await t._writeBLECharacteristicValue.call(this, arrayBuffer) if (err != null) { var data1 = { success: false, data: err } callback(data1) return false } var data1 = { success: true, data: res } callback(data1) console.log("数据发送成功!") return true } // 打开蓝牙适配器状态监听 onBLEConnectionStateChange() { wx.onBLEConnectionStateChange(res => { // 该方法回调中可以用于处理连接意外断开等异常情况 if (!res.connected) { this.closeBLEAdapter() wx.setStorageSync("bluestatus", ""); this.emitter.emit("channel", { type: "connect", data: "蓝牙已断开" }) } }, err => { console.log('err', err) }) } // 收到设备推送的notification onBLECharacteristicValueChange() { wx.onBLECharacteristicValueChange(res => { //let arrbf = new Uint8Array(res.value) //console.log(`收到硬件数据反馈!命令码为:${arrbf[2]}`) //if (this._checkData(arrbf)) { //} let arrbf = new Uint8Array(res.value) if (arrbf[0] == 0x89 && arrbf[1] == 0x89) { let dataLength = ((arrbf[10] << 8) & 0xff00) + (arrbf[11] & 0x00ff) this.recPktLength = 13 + dataLength this.receivePacket = new Uint8Array(this.recPktLength) this.recPktOffset = 0 console.log("开始接收数据:length= " + arrbf.length + " data= " + arrbf) this.receivePacket.set(arrbf, this.recPktOffset) this.recPktOffset += arrbf.length; if (this.recPktOffset == this.recPktLength) { this.getReceivePacket(this.receivePacket) } } else { console.log("继续接收数据:length= " + arrbf.length + " data= " + arrbf) this.receivePacket.set(arrbf, this.recPktOffset) this.recPktOffset += arrbf.length; if (this.recPktOffset == this.recPktLength) { this.getReceivePacket(this.receivePacket) } } }) } /* _uploadInfo(message) { console.log("-- 准备数据同步!", this._mapToArray(message)) let bleorder = wx.getStorageSync("bleorder"); let blecabinet = wx.getStorageSync("blecabinet") HTTP({ url: "cabinet/uploadBlueData", methods: "post", data: { cabinetQrCode: blecabinet, order: bleorder, message: this._mapToArray(message) } }).then(res => { console.log("✔ 数据同步成功!") }, err => { console.log('✘ 数据同步失败', err) }) } */ _mapToArray(arrbf) { let arr = [] arrbf.map(item => { arr.push(item) }) return arr } // 校验数据正确性 _checkData(arrbf) { let packetLen = arrbf.length; console.log("接收数据:" + arrbf) // 校验帧头帧尾 if (arrbf[0] != 0x89 || arrbf[1] != 0x89) { console.log('不是该设备返回的包') return false } if (packetLen < 14) { console.log("包长太短,不是该设备返回的包"); return false; } let dataLength = ((arrbf[10] << 8) & 0xff00) + (arrbf[11] & 0x00ff); if (dataLength != (packetLen - 13)) { let calLen = packetLen - 13; console.log("✘ 数据长度错误: " + dataLength + " is not " + calLen); return false; } //校验包 let check = arrbf[0]; for (let i = 1; i < packetLen - 1; i++) check ^= arrbf[i]; if (check != arrbf[packetLen - 1]) { console.log("crc校验错误,请重发." + check); return false; } console.log('✔ 数据校验成功,接收完整!') return true } getReceivePacket(arrbf) { let that = this let packetLen = arrbf.length; console.log("接收数据:" + arrbf) // 校验帧头帧尾 if (arrbf[0] != 0x89 || arrbf[1] != 0x89) { console.log('不是该设备返回的包') return [0]; } if (packetLen < 14) { console.log("包长太短,不是该设备返回的包"); return [0]; } let dataLength = ((arrbf[10] << 8) & 0xff00) + (arrbf[11] & 0x00ff); if (dataLength != (packetLen - 13)) { let calLen = packetLen - 13; console.log("✘ 数据长度错误: " + dataLength + " is not " + calLen); return [0]; } //校验包 let check = arrbf[0]; for (let i = 1; i < packetLen - 1; i++) check ^= arrbf[i]; if (check != arrbf[packetLen - 1]) { console.log("crc校验错误,请重发." + check); return [0]; } //数据解密 let key = arrbf[3]; let data_offset = 12; let result = new Uint8Array(dataLength) for (let i = 0; i < dataLength; i++) { result[i] = arrbf[i + data_offset]; result[i] = (result[i] ^ (key ^ i)); result[i] += (dataLength - i) ^ key; } console.log('✔ 数据校验成功,接收完整! packet= ' + arrbf) if (result[0] == 25 && result[result.length - 1] == 2) { //蓝牙录入指纹02,设备返回指纹ID app.globalData.fingerprintId = result[22] } if (result[0] == 25 && (result[result.length - 1] == 3 || result[result.length - 1] == 2 || result[result.length - 1] == 1)) { //蓝牙录入指纹01 app.globalData.backdata = result[result.length - 1] } if (result[0] == 83 && result[1] == 1) { app.globalData.stop29 = true } if (result[0] == 49 && result[1] == 1) { //蓝牙开锁 app.globalData.openlock = result[1] } console.log('解密明文 result= ' + result) // switch (arrbf[2]) { // case 0x53: // case 0x13: // case 0x58: // this.bleRspRecord(arrbf) // break; // } return result; } bleRspRecord(val) { var array = [] val.forEach(element => { array.push(element) }); var data = { code: "ble/deviceReport", data: { value: array, deviceNum: app.globalData.deviceNum } } console.log(app.globalData.deviceNum,data) WXAPI.sendCommand(data).then(res => { }) } } export default BLEHandler