| 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
 |