You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

360 lines
12 KiB

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