ebike-ui/ebike-user/utils/bluetooth.js
2025-04-28 15:37:57 +08:00

360 lines
9.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { AES128ECBEncrypt } from '@/utils/aes_util.js';
export default bluetooth = {
serviceId: '0000FFF0-0000-1000-8000-00805F9B34FB',
characteristicId: '0000FFF6-0000-1000-8000-00805F9B34FB',
deviceId: '',
blueSignal:'',
ecuSn:'',
blueState: 0,
blueMessage: '',
discovery:() => {
this.blueState = 0;
this.blueMessage = '';
uni.startBluetoothDevicesDiscovery({
success(res) {
if(res.errno == 0){
uni.onBluetoothDeviceFound(function (res) {
const devices = res.devices;
for(let i=0;i < devices.length; i++){
if(devices[i].localName == "ECU-" + this.ecuSn){
// 停止搜索
this.stopdiscovery();
this.blueState = 1;
this.blueMessage = '连接成功';
this.deviceId = devices[i].deviceId;
this.blueSignal = devices[i].RSSI;
this.bleconnection();
break;
}
}
});
setTimeout(function () {
if(this.blueState == 0) {
this.blueMessage = "未发现蓝牙设备";
this.blueState = -1;
}
//停止搜索
this.stopdiscovery();
}, 120000);
}
},
fail(err) {
this.blueMessage = "未发现蓝牙设备";
this.blueState = -1;
}
});
},
stopdiscovery:() =>{
uni.stopBluetoothDevicesDiscovery({
success(res) {
// if(res.errno != 0) {
// this.showmessage("停止蓝牙搜索失败", 'stopdiscovery');
// }
},
fail(){
// this.showmessage("停止蓝牙搜索失败", 'stopdiscovery');
}
});
},
bleconnection:() =>{
uni.createBLEConnection({
deviceId: this.deviceId,
success(res) {
this.startnotify();
},
fail(err) {
this.blueMessage = "蓝牙连接失败";
this.blueState = -1;
}
});
},
startnotify:() =>{
uni.notifyBLECharacteristicValueChange({
state:true,
deviceId: this.deviceId,
serviceId: this.serviceId,
characteristicId: this.characteristicId,
success(res) {
uni.onBLECharacteristicValueChange(function(res){
var hex = this.buftohex(res.value);
if (hex.length > 10) {
var header = hex.substring(0, 4);
if (header == '6774') {
var contentL1 = hex.substring(4, 6);
var contentL = parseInt(contentL1, 16);
if ((contentL + 5) * 2 == hex.length) {
//console.log('完整的一条数据contentL=', contentL)
this.distributecommandswithdatastr(hex)
} else if ((contentL + 5) * 2 > hex.length) { //需要分包接受数据
// 第一次接受分包数据
self.responseStr = hex;
//console.log('分包接受数据未实现', hex)
//console.log('第一次接受分包数据contentL2=', contentL)
} else { //数据异常 ,查看
//console.log('数据异常 ,查看1', hex)
}
return;
}
} else {
//console.log('分包接受数据未实现', hex)
}
});
this.verification();
},
fail(err) {
this.blueMessage = "蓝牙连接失败";
this.blueState = -1;
}
});
},
verification = (mac, key1, key2) => {
if (mac && key1 && key2) {
//数据总长度为21第一天长度20
var buffer = new ArrayBuffer(20)
var dataView = new DataView(buffer)
dataView.setUint32(0, 0X6774108a)
var sourceKey1 = mac + key1
var AESEncrypt = AES128ECBEncrypt(sourceKey1, key2)
if (AESEncrypt.length != 32) {
return;
}
for (var i = 0; i < 4; i++) {
var subStr = AESEncrypt.substring(i * 8, i * 8 + 8, 16);
dataView.setUint32(i * 4 + 4, parseInt(subStr, 16)); //4字节01523947(16进制)-->>10进制数字-->放入dateView
}
var i;
var bcc;//17为数据长度16+1
for (i = 0; i < 17; i++) {
bcc ^= dataView.getInt8(i + 3);
}
var buffer2 = new ArrayBuffer(1)
var dataView2 = new DataView(buffer2)
dataView2.setUint8(0, bcc)
console.log('验证', this.buftohex(buffer));
this.writecharacteristicvalue(buffer);
setTimeout(() => {
this.writecharacteristicvalue(buffer2);
}, 300);
} else {
var buffer = new ArrayBuffer(5)
var dataView = new DataView(buffer)
dataView.setUint32(0, 0X6774008a)
dataView.setUint8(4, 0x8a)
this.writecharacteristicvalue(buffer);
}
},
writecharacteristicvalue = (buffer) => {
uni.writeBLECharacteristicValue({
deviceId: this.deviceId,
serviceId: this.serviceId,
characteristicId: this.characteristicId,
value: buffer,
success: function (res) {
console.log('writeBLECharacteristicValue success', res.errMsg)
},
fail: function (res) {
console.log('writeBLECharacteristicValue fail', res.errMsg)
this.blueMessage = "蓝牙连接失败";
this.blueState = -1;
},
complete: function (res) {
}
});
},
verificationTimes:0,
distributecommandswithdatastr:(hex) => {
var cmd = hex.substring(6, 8);
var code = hex.substring(8, 10);
var errCode = code
var desDic = {}
var des = '';
if (code == '00') {
des = '成功'
errCode = 0
} else if (code == 'ff') { //-1
des = '锁已打开'
errCode = -1
} else if (code == 'fe') { //-2
des = '电量不足'
errCode = -2
} else if (code == 'fd') { //-3
des = '加密验证失败'
errCode = -3
} else if (code == 'fc') { //-4
des = '内存空间不足'
errCode = -4
} else if (code == 'fb') { //-5
des = '格式错误'
errCode = -5
} else if (code == 'fa') { //-6
des = '没有验证或验证失败'
errCode = -6
desDic['mac'] = hex.substring(10, 22);
desDic['key'] = hex.substring(22, 30);
} else if (code == 'f9') { //-7
des = 'flash写入失败'
errCode = -7
} else if (code == 'f8') { //-8
des = '数据空'
errCode = -8
} else if (code == 'f7') { //-9
des = '操作失败'
errCode = -9
} else if (code == 'f6') { //-10
des = '运输模式下无法执行该指令'
errCode = -10
} else if (code == 'f5') { //-11
des = '锁车失败,车辆未停止'
errCode = -11
} else if (code == 'f4') { //-12
des = '未检测到道钉信息'
errCode = -12
} else if (parseInt(code,16) == 149) { //
des = '摄像头正在工作中'
errCode = parseInt(code,16)
} else if (parseInt(code,16) == 150) { //
des = '摄像头离线'
errCode = parseInt(code,16)
} else if (parseInt(code,16) == 151) { //
des = '车辆不在使用中(临时停车或是还车中)无法使用摄像头还车'
errCode = parseInt(code,16)
} else if (parseInt(code,16) == 152) { //
des = '执行命令超时'
errCode = parseInt(code,16)
} else if (parseInt(code,16) == 153) { //
des = '摄像头执行失败'
errCode = parseInt(code,16)
} else if (parseInt(code,16) == 154) { //
des = '不在站点中或没有垂直停车'
errCode = parseInt(code,16)
} else {
des = '未知错误码' + code
errCode = code
}
if (cmd == '4a') { //验证
if (verificationTimes >= 1) {
verificationTimes = 0
if (errCode == -6) {
verificationTimes = 1;
this.verification(desDic.mac, desDic.key, '6666660000888888')
return;
}
//验证成功
this.blueState = 10;
this.blueMessage = '验证成功';
return;
} else {
verificationTimes += 1;
}
if (errCode == -6) {
this.verification(desDic.mac, desDic.key, '6666660000888888')
}
}
},
buftohex: (buffer) => {
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
},
closeconn: () =>{
uni.closeBLEConnection({
deviceId: this.deviceId,
success(res) {
}
});
},
execcommon = (comm) => {
switch(comm){
case "openLock": //开锁
var buffer = new ArrayBuffer(5);
var dataView = new DataView(buffer);
dataView.setUint32(0, 0X67740082);
dataView.setUint8(4, 0x82);
this.writecharacteristicvalue(buffer);
break;
case "closeLock": //关锁
var buffer = new ArrayBuffer(5);
var dataView = new DataView(buffer);
dataView.setUint32(0, 0X67740081);
dataView.setUint8(4, 0x81);
this.writecharacteristicvalue(buffer);
break;
// case "openBatteryHouse": //打开电池仓
// var buffer = new ArrayBuffer(6);
// var dataView = new DataView(buffer);
// dataView.setUint32(0, 0X67740189);
// dataView.setUint8(4, 0);
// var i;
// var bcc;
// for (i = 0; i < 2; i++) {
// bcc ^= dataView.getInt8(i + 3);
// }
// dataView.setInt8(5, bcc);
// this.writecharacteristicvalue(buffer);
// break;
// case "closeBatteryHouse": //关闭电池仓
// var buffer = new ArrayBuffer(6);
// var dataView = new DataView(buffer);
// dataView.setUint32(0, 0X67740189);
// dataView.setUint8(4, 1);
// var i;
// var bcc;
// for (i = 0; i < 2; i++) {
// bcc ^= dataView.getInt8(i + 3);
// }
// dataView.setInt8(5, bcc);
// this.writecharacteristicvalue(buffer);
// break;
}
},
openbluetooth:() => {
uni.openBluetoothAdapter({
success(res) {
if(res.errno == 0){
this.discovery();
}
else
{
this.blueMessage = "蓝牙未开启或未授权";
this.blueState = -1;
}
},
fail(err) {
let errmsg = err.errMsg;
if(err.errCode == 10001){
}
this.blueMessage = "蓝牙未开启或未授权";
this.blueState = -1;
}
});
uni.onBluetoothAdapterStateChange(function (res) {
if(res["available"]){
this.discovery();
}
else {
this.blueMessage = "蓝牙未开启或未授权";
this.blueState = -1;
}
});
},
openlock:() =>{
if(this.ecuSn == ''){
this.blueMessage = "开锁失败";
}
this.openbluetooth();
let connTime = 0;
let timer = setInterval(() =>{
if(this.blueState == 10){
clearInterval(timer);
this.execcommon("openLock");
}
else if(connTime > 6){
clearInterval(timer);
this.blueMessage = "开锁失败";
}
connTime += 1;
}, 10000);
}
}