wx-starlock/stores/bluetooth.js
范鹏 452d7e5ffe 1. 修复重置提示显示后立即消失bug
2. 添加连接设备失败重试逻辑
3. 设置页显示超级管理员可用时间
2024-09-06 09:46:08 +08:00

1716 lines
57 KiB
JavaScript
Raw 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.

/**
* @description 蓝牙数据持久化
*/
import { defineStore } from 'pinia'
import crc from 'crc'
import { sm4 } from 'sm-crypto'
import { md5 } from 'js-md5'
import { getServerDatetime } from '@/api/check'
import { getUserNoListRequest, updateLockUserNoRequest } from '@/api/key'
import { updateElectricQuantityRequest } from '@/api/room'
import { reportOpenDoorRequest } from '@/api/lockRecords'
import { updateTimezoneOffsetRequest } from '@/api/user'
// 定时器
let timer
// 特性值回调
let characteristicValueCallback = null
// 搜索次数
let searchNumber = 10
// 搜索提示标志
let searchTipFlag = true
// 命令ID
const cmdIds = {
// 获取公钥
getPublicKey: 0x3090,
// 获取私钥
getCommKey: 0x3091,
// 获取锁状态
getLockStatus: 0x3040,
// 新增用户
addUser: 0x3001,
// 开门
openDoor: 0x3005,
// 重置设备
resetDevice: 0x3004,
// 清理用户
cleanUser: 0x300C,
// 扩展命令
expandCmd: 0x3030
}
// 子命令ID
const subCmdIds = {
// 设置开锁密码
setLockPassword: 3,
// 重置开锁密码
resetLockPassword: 19
}
export const useBluetoothStore = defineStore('ble', {
state() {
return {
/*
* 蓝牙状态
* -1 未知(初始状态)
* 0 正常
* 1 系统蓝牙未打开
* 2 小程序蓝牙功能被禁用
* 3 系统蓝牙未打开且小程序蓝牙功能被禁用
*/
bluetoothStatus: -1,
// 设备列表
deviceList: [],
// 当前锁信息
currentLockInfo: {},
// 消息序号
messageCount: 1,
// 是否初始化蓝牙
isInitBluetooth: false,
// 服务器时间
serverTimestamp: 0,
// 设备keyID
keyId: '0',
// 刚绑定的设备名称
bindedDeviceName: ''
}
},
actions: {
// 保存刚绑定的设备名称
updateBindedDeviceName(name) {
this.bindedDeviceName = name
setTimeout(() => {
this.bindedDeviceName = ''
console.log('清空设备名称')
}, 15000)
},
// 更新keyId
updateKeyId(keyId) {
this.keyId = keyId
},
// 二进制转字符串
uint8ArrayToString(uint8Array) {
let str = ''
for (let i = 0; i < uint8Array.length; i++) {
if (uint8Array[i] !== 0) {
str += String.fromCharCode(uint8Array[i]);
}
}
return str
},
// 更新服务端时间戳
async updateServerTimestamp() {
const { code, data, message } = await getServerDatetime({})
if(code === 0) {
this.serverTimestamp = parseInt(data.date / 1000)
}
return { code, data, message }
},
// 关闭全部蓝牙监听并关闭蓝牙模拟
closeAllBluetooth() {
uni.offBluetoothAdapterStateChange()
uni.closeBluetoothAdapter({
success(res) {
console.log('关闭蓝牙模块', res)
}
})
},
// 初始化并监听
async initAndListenBluetooth(tipFlag) {
// 初始化蓝牙
const initResult = await this.initBluetooth(tipFlag)
if (initResult) {
// 更新蓝牙初始化状态
this.updateInitBluetooth(true)
// 监听蓝牙开关状态
this.onBluetoothState()
// 监听蓝牙连接状态
this.onBluetoothConnectStatus()
// 监听设备特征值变化
this.onBluetoothCharacteristicValueChange()
return true
} else {
return false
}
},
// 更新是否初始化蓝牙字段
updateInitBluetooth(value) {
this.isInitBluetooth = value
},
// 初始化蓝牙模块
initBluetooth(tipFlag = true) {
const that = this
// 初始化蓝牙模块
return new Promise(resolve => {
uni.openBluetoothAdapter({
success() {
that.bluetoothStatus = 0
console.log('蓝牙初始化成功')
resolve(true)
},
fail(err) {
console.log('蓝牙初始化失败', err)
// 系统蓝牙未打开
if(err.errCode === 10001) {
if(that.bluetoothStatus === 2) {
that.bluetoothStatus = 3
} else {
that.bluetoothStatus = 1
}
}
// 小程序蓝牙功能被禁用
if(err.errno === 103) {
if(that.bluetoothStatus === 1) {
that.bluetoothStatus = 3
} else {
that.bluetoothStatus = 2
}
}
// 蓝牙已经初始化
if(err.errMsg === 'openBluetoothAdapter:fail already opened') {
resolve(true)
return
}
if(err.errno === 3 && tipFlag) {
uni.showModal({
title: '提示',
content: '蓝牙功能需要附近设备权限,请前往设置开启微信的附近设备权限后再试',
showCancel: false,
confirmText: '确定',
success(res) {
if (res.confirm) {
uni.openAppAuthorizeSetting({
success (res) {
console.log(res)
}
})
}
}
})
}
resolve(false)
}
})
})
},
// 监听蓝牙状态变化
onBluetoothState() {
const that = this
uni.onBluetoothAdapterStateChange((res) => {
console.log('蓝牙状态改变', res)
if(that.bluetoothStatus === 3 && res.available) {
that.bluetoothStatus = 2
} else if (that.bluetoothStatus === 2 && !res.available) {
that.bluetoothStatus = 3
} else if (that.bluetoothStatus === 1 && res.available) {
that.bluetoothStatus = 0
} else if (that.bluetoothStatus === 0 && !res.available){
that.bluetoothStatus = 1
} else if (that.bluetoothStatus === -1) {
if(res.available) {
that.bluetoothStatus = 0
} else {
that.bluetoothStatus = 1
}
}
})
},
// 监听蓝牙设备连接状态
onBluetoothConnectStatus() {
const that = this
uni.onBLEConnectionStateChange(function (res) {
if(res.deviceId === that.currentLockInfo.deviceId) {
console.log('设备连接状态改变', res)
that.updateCurrentLockInfo({
...that.currentLockInfo,
connected: res.connected
})
}
})
},
// 解析特征值
parsingCharacteristicValue(binaryData) {
const that = this
// 0x20 明文 0x22 SM4事先约定密钥 0x23 SM4设备指定密钥
if(binaryData[7] === 0x20) {
if(binaryData[12] * 256 + binaryData[13] === cmdIds.getPublicKey) {
if(binaryData[14] === 0) {
that.updateCurrentLockInfo({
...that.currentLockInfo,
publicKey: [...binaryData.slice(15, 31)]
})
}
characteristicValueCallback({
code: binaryData[14]
})
}
} else if(binaryData[7] === 0x22) {
// 截取入参
const cebBinaryData = binaryData.slice(12, binaryData.length - 2)
// 解密
const key = new Uint8Array(16)
for (let i = 0; i < that.currentLockInfo.name.length; i++) {
key[i] = that.currentLockInfo.name.charCodeAt(i)
}
const decrypted = sm4.decrypt(cebBinaryData, key, { mode: 'ecb', output: 'array' })
console.log('ecb解密后的数据', decrypted)
if(decrypted[0] * 256 + decrypted[1] === cmdIds.getCommKey) {
if(decrypted[2] === 0) {
that.updateCurrentLockInfo({
...that.currentLockInfo,
commKey: decrypted.slice(3, 19),
signKey: decrypted.slice(19, 35),
pwdTimestamp: this.arrayToTimestamp(decrypted.slice(35, 39)) * 1000
})
console.log('commKey', Array.from(that.currentLockInfo.commKey))
console.log('signKey', Array.from(that.currentLockInfo.signKey))
}
characteristicValueCallback({
code: decrypted[2]
})
}
} else {
const cebBinaryData = binaryData.slice(12, binaryData.length - 2)
const decrypted = sm4.decrypt(cebBinaryData, that.currentLockInfo.commKey, { mode: 'ecb', output: 'array' })
console.log('ecb解密后的数据', decrypted)
const cmdId = decrypted[0] * 256 + decrypted[1]
switch (cmdId) {
case cmdIds.getLockStatus:
if (decrypted[2] === 0) {
const lockConfig = {
vendor: that.uint8ArrayToString(decrypted.slice(3, 23)),
product: decrypted[23],
model: that.uint8ArrayToString(decrypted.slice(24, 44)),
fwVersion: that.uint8ArrayToString(decrypted.slice(44, 64)),
hwVersion: that.uint8ArrayToString(decrypted.slice(64, 84)),
serialNum0: that.uint8ArrayToString(decrypted.slice(84, 100)),
serialNum1: that.uint8ArrayToString(decrypted.slice(100, 116)),
btDeviceName: that.uint8ArrayToString(decrypted.slice(116, 132)),
electricQuantity: decrypted[132],
electricQuantityStandby: decrypted[133],
restoreCount: decrypted[134] * 256 + decrypted[135],
restoreDate: this.arrayToTimestamp(decrypted.slice(136, 140)),
icPartNo: that.uint8ArrayToString(decrypted.slice(140, 150)),
indate: this.arrayToTimestamp(decrypted.slice(150, 154)),
mac: that.uint8ArrayToString(decrypted.slice(154, 174)),
timezoneOffset: new Date().getTimezoneOffset() * 60
}
that.updateCurrentLockInfo({
...that.currentLockInfo,
featureValue: that.uint8ArrayToString(decrypted.slice(175, 175 + decrypted[174])),
featureSettingValue: that.uint8ArrayToString(decrypted.slice(176 + decrypted[174], 176 + decrypted[174] + decrypted[175 + decrypted[174]])),
featureSettingParams: Array.from(decrypted.slice(176 + decrypted[174] + decrypted[175 + decrypted[174]])),
lockConfig
})
console.log('获取锁状态成功', that.currentLockInfo.lockConfig)
}
characteristicValueCallback({
code: decrypted[2]
})
break
case cmdIds.addUser:
that.updateCurrentLockInfo({
...that.currentLockInfo,
token: decrypted.slice(42,46)
})
if(decrypted[46] === 0) {
that.updateCurrentLockInfo({
...that.currentLockInfo,
lockUserNo: decrypted[47] * 256 + decrypted[48]
})
}
console.log('添加用户结果', decrypted[46], that.currentLockInfo.token)
characteristicValueCallback({
code: decrypted[46]
})
break
case cmdIds.expandCmd:
const subCmdId = decrypted[3]
switch (subCmdId) {
case subCmdIds.resetLockPassword:
that.updateCurrentLockInfo({
...that.currentLockInfo,
token: decrypted.slice(5,9)
})
characteristicValueCallback({
code: decrypted[2]
})
if(decrypted[2] === 0) {
that.updateCurrentLockInfo({
...that.currentLockInfo,
encrpyKey: decrypted.slice(9, 17)
})
}
break
case subCmdIds.setLockPassword:
that.updateCurrentLockInfo({
...that.currentLockInfo,
token: decrypted.slice(5,9)
})
characteristicValueCallback({
code: decrypted[2],
data: {
status: decrypted[11]
}
})
break
}
break
case cmdIds.openDoor:
that.updateCurrentLockInfo({
...that.currentLockInfo,
token: decrypted.slice(2,6)
})
console.log('开门', decrypted[6], that.currentLockInfo.token)
characteristicValueCallback({
code: decrypted[6]
})
if(decrypted[6] === 0) {
updateElectricQuantityRequest({
lockId: that.currentLockInfo.lockId,
electricQuantity: decrypted[7],
electricQuantityStandby: decrypted[9]
}).then(res => {
if(res.code === 0) {
that.updateCurrentLockInfo({
...that.currentLockInfo,
electricQuantityDate: res.data.electricQuantityDate
})
}
})
reportOpenDoorRequest({
lockId: that.currentLockInfo.lockId,
keyId: that.keyId,
}).then(res => {
console.log('上报开门结果', res)
})
updateTimezoneOffsetRequest({
timezoneOffset: new Date().getTimezoneOffset() * 60
}).then(res => {
console.log('上报时区结果', res)
})
}
break
default:
that.updateCurrentLockInfo({
...that.currentLockInfo,
token: decrypted.slice(2,6)
})
console.log('默认结果', decrypted[6], that.currentLockInfo.token)
characteristicValueCallback({
code: decrypted[6]
})
break
}
}
},
// 监听蓝牙设备特征值改变
onBluetoothCharacteristicValueChange() {
const that = this
// 完整数据
let completeArray
// 完整内容数据长度
let length
console.log('开始监听特征值改变')
uni.onBLECharacteristicValueChange(function (res) {
if(res.deviceId === that.currentLockInfo.deviceId) {
let binaryData = new Uint8Array(res.value)
if(binaryData[0] === 0xEF && binaryData[1] === 0x01 && binaryData[2] === 0xEE && binaryData[3] === 0x02) {
length = binaryData[8] * 256 + binaryData[9]
if(length + 14 > binaryData.length) {
completeArray = binaryData
} else {
that.parsingCharacteristicValue(binaryData)
}
} else {
if(completeArray) {
const combinedArray = new Uint8Array(completeArray.length + binaryData.length)
combinedArray.set(completeArray, 0);
combinedArray.set(binaryData, completeArray.length)
completeArray = combinedArray
if(length + 14 === completeArray.length) {
that.parsingCharacteristicValue(completeArray)
completeArray = null
}
}
}
}
})
},
// 开始搜索蓝牙设备
getBluetoothDevices() {
const that = this
if(this.bluetoothStatus !== 0) {
console.log('搜索未执行', this.bluetoothStatus)
this.getBluetoothStatus()
return
}
this.deviceList = []
uni.startBluetoothDevicesDiscovery({
success: function (res) {
setTimeout(() => {
that.searchBluetoothDevices()
}, 300)
},
fail: async function (res) {
console.log('开始搜索失败', res)
if(res.errno === 1509008) {
uni.showModal({
title: '提示',
content: '安卓手机蓝牙功能需要定位权限,请前往设置开启微信的定位权限后再试',
showCancel: false,
success(res) {
if (res.confirm) {
uni.openAppAuthorizeSetting({
success (res) {
console.log(res)
}
})
}
uni.navigateBack()
}
})
}
if(res.errCode === 10000) {
// 重新初始化蓝牙适配器
await that.initBluetooth()
that.getBluetoothDevices()
}
}
})
},
// 定时查询蓝牙设备
searchBluetoothDevices() {
const that = this
if(this.bluetoothStatus !== 0) {
console.log('搜索未执行', this.bluetoothStatus)
this.getBluetoothStatus()
return
}
timer = setInterval(() => {
uni.getBluetoothDevices({
success(res) {
searchNumber--
if(searchNumber === 0 && searchTipFlag) {
uni.showModal({
title: '提示',
content: '长时间未搜索到任何设备,请确认微信的附近设备权限开启后再试',
showCancel: false,
success() {
uni.openAppAuthorizeSetting({
success (res) {
console.log(res)
}
})
uni.navigateBack()
}
})
}
const deviceList = res.devices
if(deviceList.length !== 0) {
searchTipFlag = false
}
that.deviceList = []
for(let i = 0; i < deviceList.length; i++) {
if(deviceList[i]?.advertisServiceUUIDs) {
const uuid = deviceList[i]?.advertisServiceUUIDs[0]
if(uuid && uuid.slice(2,8)==='758824' && uuid.slice(30,32)==='00') {
that.deviceList.push(deviceList[i])
}
}
}
console.log('设备列表', that.deviceList)
},
fail: async function (res) {
console.log('获取设备列表失败', res)
if(res.errCode === 10000) {
// 重新初始化蓝牙适配器
await that.initBluetooth()
}
}
})
}, 1000)
},
// 停止搜索蓝牙设备
stopGetBluetoothDevices() {
searchNumber = 10
searchTipFlag = true
clearInterval(timer)
uni.stopBluetoothDevicesDiscovery()
},
// 蓝牙状态提示
getBluetoothStatus() {
if(this.bluetoothStatus === 1) {
uni.showModal({
title: '提示',
content: '蓝牙尚未打开,请先打开蓝牙',
showCancel: false,
success(res) {
if (res.confirm) {
wx.openSystemBluetoothSetting({
success (res) {
console.log(res)
}
})
}
}
})
} else if(this.bluetoothStatus === 2 || this.bluetoothStatus === 3) {
uni.showModal({
title: '提示',
content: '小程序蓝牙功能被禁用,请打开小程序蓝牙权限',
showCancel: false,
confirmText: '去设置',
success(res) {
if(res.confirm) {
uni.openSetting()
}
}
})
}
},
// 检查小程序设置
checkSetting() {
const that = this
return new Promise((resolve) => {
uni.getSetting({
async success(res) {
const bluetooth = res.authSetting['scope.bluetooth']
if(that.bluetoothStatus === -1) {
if(bluetooth !== false) {
that.bluetoothStatus = 0
} else {
that.bluetoothStatus = 2
}
} else if(that.bluetoothStatus === 0 && bluetooth === false) {
that.bluetoothStatus = 2
} else if(that.bluetoothStatus === 1 && bluetooth === false) {
that.bluetoothStatus = 3
} else if(that.bluetoothStatus === 2 && bluetooth !== false) {
that.bluetoothStatus = 0
await that.initBluetooth()
} else if(that.bluetoothStatus === 3 && bluetooth !== false) {
that.bluetoothStatus = 1
await that.initBluetooth()
that.onBluetoothState()
}
console.log('蓝牙权限', bluetooth, that.bluetoothStatus)
resolve(bluetooth)
},
fail() {
resolve(false)
}
})
})
},
// 连接蓝牙设备+获取设备服务+获取设备特征值
connectBluetoothDevice(number = 0) {
const that = this
return new Promise((resolve) => {
if(that.bluetoothStatus !== 0) {
console.log('连接未执行', that.bluetoothStatus)
that.getBluetoothStatus()
resolve(false)
return
}
uni.createBLEConnection({
deviceId: that.currentLockInfo.deviceId,
success(res) {
console.log('连接成功', res)
// 获取设备服务
uni.getBLEDeviceServices({
deviceId: that.currentLockInfo.deviceId,
success (res) {
let serviceId
for(let i = 0; i < res.services.length; i++) {
if(res.services[i].uuid.indexOf('FFF0') !== -1) {
serviceId = res.services[i].uuid
}
}
// 获取设备对应服务的特征值
uni.getBLEDeviceCharacteristics({
deviceId: that.currentLockInfo.deviceId,
serviceId: serviceId,
success (res) {
let notifyCharacteristicId
let writeCharacteristicId
for(let i = 0; i < res.characteristics.length; i++) {
const characteristic = res.characteristics[i]
if(characteristic.properties.notify) {
notifyCharacteristicId = characteristic.uuid
}
if(characteristic.properties.write) {
writeCharacteristicId = characteristic.uuid
}
}
that.updateCurrentLockInfo({
...that.currentLockInfo,
serviceId,
notifyCharacteristicId,
writeCharacteristicId
})
that.notifyBluetoothCharacteristicValueChange()
resolve(true)
},
fail(res) {
if(res.errCode === 10006) {
uni.showToast({
title: '连接失败,请靠近设备并保持设备处于唤醒状态',
icon: 'none'
})
}
console.log('获取设备特征值失败', res)
resolve(false)
}
})
},
fail(res) {
if(res.errCode === 10006) {
uni.showToast({
title: '连接失败,请靠近设备并保持设备处于唤醒状态',
icon: 'none'
})
}
console.log('获取设备服务失败', res)
resolve(false)
}
})
},
async fail(res) {
if(res.errno === 1509007) {
resolve(true)
return
}
if(res.errno === 1509001 && number < 1) {
// 重新连接
resolve(await that.connectBluetoothDevice(number + 1))
}
uni.showToast({
title: '连接失败,请靠近设备并保持设备处于唤醒状态',
icon: 'none'
})
console.log('连接失败', res)
resolve(false)
}
})
})
},
// 更新当前锁信息
updateCurrentLockInfo(lockInfo) {
console.log('更新当前锁信息', lockInfo)
this.currentLockInfo = lockInfo
},
// 订阅设备特征值改变
notifyBluetoothCharacteristicValueChange() {
const that = this
uni.notifyBLECharacteristicValueChange({
state: true,
deviceId: that.currentLockInfo.deviceId,
serviceId: that.currentLockInfo.serviceId,
characteristicId: that.currentLockInfo.notifyCharacteristicId,
success(res) {
console.log('订阅成功', res)
},
fail(res) {
console.log('订阅失败', res)
}
})
},
// 断开蓝牙连接
closeBluetoothConnection() {
const that = this
uni.closeBLEConnection({
deviceId: that.currentLockInfo.deviceId,
success(res) {
console.log('断开连接成功', res)
},
fail(res) {
console.log('断开连接失败', res)
}
})
},
// 周数组转换
convertWeekdaysToNumber(weekDay) {
let weekStr = '00000000'
for (const day of weekDay) {
const index = day % 7 // 将周日的索引转换为0
weekStr = weekStr.substring(0, index) + '1' + weekStr.substring(index + 1)
}
// 倒序 weekStr
weekStr = weekStr.split('').reverse().join('')
const weekRound = parseInt(weekStr, 2)
return weekRound
},
// 查找设备并连接
async searchAndConnectDevice() {
const that = this
let timer1
let timer2
return new Promise((resolve) => {
uni.startBluetoothDevicesDiscovery({
success: function () {
timer2 = setTimeout(() => {
uni.stopBluetoothDevicesDiscovery()
clearInterval(timer1)
resolve({ code: -1 })
}, 10500)
timer1 = setInterval(() => {
uni.getBluetoothDevices({
success(res) {
const deviceList = res.devices
for(let i = 0; i < deviceList.length; i++) {
if(deviceList[i]?.name === that.currentLockInfo.name) {
const uuid = deviceList[i]?.advertisServiceUUIDs[0]
console.log('设备UUID', uuid, uuid.slice(2,8), uuid.slice(30,32))
if(uuid && uuid.slice(2,8)==='758824' && (uuid.slice(30,32)==='01' || that.bindedDeviceName === that.currentLockInfo.name)) {
uni.stopBluetoothDevicesDiscovery()
clearTimeout(timer2)
clearInterval(timer1)
resolve({
code: 0,
data: {
deviceId: deviceList[i].deviceId
}
})
break
} else if(uuid && uuid.slice(2,8)==='758824' && uuid.slice(30,32)==='00') {
uni.stopBluetoothDevicesDiscovery()
clearTimeout(timer2)
clearInterval(timer1)
uni.hideLoading()
uni.showToast({
title: '锁已被重置,请重新绑定',
icon: 'none'
})
resolve({
code: -2
})
break
} else {
uni.stopBluetoothDevicesDiscovery()
clearTimeout(timer2)
clearInterval(timer1)
resolve({
code: -3
})
break
}
}
}
},
fail: async function (res) {
console.log('获取设备列表失败', res)
if(res.errCode === 10000) {
// 重新初始化蓝牙适配器
await that.initBluetooth()
}
}
})
}, 1000)
},
fail: async function (res) {
console.log('开始搜索失败', res)
if(res.errCode === 10000) {
// 重新初始化蓝牙适配器
await that.initBluetooth()
that.searchAndConnectDevice()
} else if(res.errno === 1509008) {
uni.showModal({
title: '提示',
content: '安卓手机蓝牙功能需要定位权限,请前往设置开启微信的定位权限后再试',
showCancel: false,
success(res) {
if (res.confirm) {
uni.openAppAuthorizeSetting({
success (res) {
console.log(res)
}
})
}
}
})
resolve({
code: -1
})
} else {
resolve({
code: -1
})
}
}
})
})
},
// 检查是否已添加为用户
async checkLockUser(flag = false) {
console.log('检查是否已添加为用户', this.currentLockInfo.lockUserNo)
if(this.currentLockInfo.lockUserNo === 0 || flag) {
const timestamp = parseInt(new Date().getTime() / 1000)
const password = (Math.floor(Math.random() * 900000) + 100000).toString()
console.log('用户未添加,开始添加用户')
const addUserParams = {
name: this.currentLockInfo.name,
keyId: this.keyId,
authUid: this.currentLockInfo.senderUserId.toString(),
uid: this.currentLockInfo.uid.toString(),
openMode: 1,
keyType: 0,
startDate: this.currentLockInfo.startDate === 0 ? timestamp : parseInt(this.currentLockInfo.startDate / 1000),
expireDate: this.currentLockInfo.endDate === 0 ? 0xffffffff : parseInt(this.currentLockInfo.endDate / 1000),
useCountLimit: this.currentLockInfo.keyType === 3 ? 1 : 0xffff,
isRound: this.currentLockInfo.keyType === 4 ? 1 : 0,
weekRound: this.currentLockInfo.keyType === 4 ? this.convertWeekdaysToNumber(this.currentLockInfo.weekDays) : 0,
startHour: this.currentLockInfo.keyType === 4 ? new Date(this.currentLockInfo.startDate).getHours() : 0,
startMin: this.currentLockInfo.keyType === 4 ? new Date(this.currentLockInfo.startDate).getMinutes() : 0,
endHour: this.currentLockInfo.keyType === 4 ? new Date(this.currentLockInfo.endDate).getHours() : 0,
endMin: this.currentLockInfo.keyType === 4 ? new Date(this.currentLockInfo.endDate).getMinutes() : 0,
role: 0,
password
}
const { code: addUserCode } = await this.addLockUser(addUserParams)
console.log('添加用户蓝牙结果', addUserCode, addUserParams)
if(addUserCode === 0) {
const { code } = await updateLockUserNoRequest({
keyId: this.keyId,
lockUserNo: this.currentLockInfo.lockUserNo
})
console.log('添加用户请求结果', code)
return true
} else if(addUserCode === 0x0c) {
console.log('用户达上限,开始清理用户')
const { code: requestCode, data: requestData } = await getUserNoListRequest({
lockId: this.currentLockInfo.lockId
})
console.log('获取用户列表请求结果', requestCode, requestData)
if(requestCode !== 0) return false
const userNoList = requestData.userNos
const { code: cleanCode } = await this.cleanLockUser({
name: this.currentLockInfo.name,
keyId: this.keyId,
authUid: this.currentLockInfo.senderUserId.toString(),
uid: this.currentLockInfo.uid.toString(),
userNoList: userNoList
})
console.log('清理用户蓝牙结果', cleanCode)
if(cleanCode === 0) {
return await this.checkLockUser()
} else {
return false
}
} else if(addUserCode === 0x0f) {
return true
} else {
return false
}
} else {
return true
}
},
// 写入特征值
async writeBLECharacteristicValue(binaryData) {
const that = this
console.log('设备ID', that.currentLockInfo.deviceId)
console.log('设备名称:', that.currentLockInfo.name)
console.log('设备主服务:', that.currentLockInfo.serviceId)
console.log('设备写入特征值:', that.currentLockInfo.writeCharacteristicId)
console.log('设备写入数据:', Array.from(binaryData))
// 次数
const count = Math.ceil(binaryData.length / 20)
for(let i = 0; i < count; i++) {
const writeData = binaryData.slice(i * 20, i === (count - 1) ? binaryData.length : (i + 1) * 20)
uni.writeBLECharacteristicValue({
deviceId: that.currentLockInfo.deviceId,
serviceId: that.currentLockInfo.serviceId,
characteristicId: that.currentLockInfo.writeCharacteristicId,
value: writeData.buffer,
fail(res) {
console.log('写入失败', res)
}
})
}
},
/*
* 生成包头
* encryptionType 加密类型 0明文1AES1282SM4事先约定密钥3SM4设备指定密钥
* originalLength 原始数据长度
* */
createPackageHeader(encryptionType, originalLength) {
// 头部数据
let headArray = new Uint8Array(12)
// 固定包头
headArray[0] = 0xEF
headArray[1] = 0x01
headArray[2] = 0xEE
headArray[3] = 0x02
// 包类型 发送
headArray[4] = 0x01
// 包序号
headArray[5] = this.messageCount / 256
headArray[6] = this.messageCount % 256
this.messageCount++
// 包标识
if(encryptionType === 0) {
headArray[7] = 0x20
} else if(encryptionType === 2) {
headArray[7] = 0x22
} else {
headArray[7] = 0x23
}
// 数据长度
if(encryptionType === 0) {
headArray[8] = originalLength / 256
headArray[9] = originalLength % 256
} else {
const length = Math.ceil(originalLength / 16) * 16
headArray[8] = length / 256
headArray[9] = length % 256
}
headArray[10] = originalLength / 256
headArray[11] = originalLength % 256
return headArray
},
// 生成包尾 头部数据+内容数据
createPackageEnd(headArray,conentArray) {
// 拼接头部和内容
let mergerArray = new Uint8Array(headArray.length + conentArray.length)
mergerArray.set(headArray)
mergerArray.set(conentArray, headArray.length)
// crc加密
const crcResult = crc.crc16kermit(mergerArray)
// 拼接crc
let newArray = new Uint8Array(mergerArray.length + 2)
newArray.set(mergerArray)
newArray.set([crcResult / 256, crcResult % 256], mergerArray.length)
return newArray
},
// 获取公钥
async getPublicKey(name) {
// 确认蓝牙状态正常
if(this.bluetoothStatus !== 0) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
return {
code: -1
}
}
// 确认设备连接正常
if(!this.currentLockInfo.connected) {
const srerchResult = await this.searchAndConnectDevice()
if(srerchResult.code !== 0) {
return srerchResult
}
this.updateCurrentLockInfo({
...this.currentLockInfo,
deviceId: srerchResult.data.deviceId
})
console.log('设备ID', this.currentLockInfo.deviceId)
const result = await this.connectBluetoothDevice()
console.log('连接结果', result)
if(!result) {
return {
code: -1
}
}
}
const headArray = this.createPackageHeader(0, 42)
const conentArray = new Uint8Array(42)
conentArray[0] = cmdIds.getPublicKey / 256
conentArray[1] = cmdIds.getPublicKey % 256
for(let i = 0; i < name.length; i++) {
conentArray[i + 2] = name.charCodeAt(i)
}
const packageArray = this.createPackageEnd(headArray, conentArray)
await this.writeBLECharacteristicValue(packageArray)
return this.getWriteResult()
},
// 获取私钥
async getCommKey(name, keyId, authUid, nowTime) {
// 确认蓝牙状态正常
if(this.bluetoothStatus !== 0) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
return {
code: -1
}
}
// 确认设备连接正常
if(!this.currentLockInfo.connected) {
const srerchResult = await this.searchAndConnectDevice()
if(srerchResult.code !== 0) {
return srerchResult
}
this.updateCurrentLockInfo({
...this.currentLockInfo,
deviceId: srerchResult.data.deviceId
})
console.log('设备ID', this.currentLockInfo.deviceId)
const result = await this.connectBluetoothDevice()
console.log('连接结果', result)
if(!result) {
return {
code: -1
}
}
}
const length = 2 + 40 + 40 + 20 + 4 + 1 + 16
const headArray = this.createPackageHeader(2, length)
const conentArray = new Uint8Array(length)
conentArray[0] = cmdIds.getCommKey / 256
conentArray[1] = cmdIds.getCommKey % 256
for (let i = 0; i < name.length; i++) {
conentArray[i + 2] = name.charCodeAt(i)
}
for(let i = 0; i < keyId.length; i++) {
conentArray[i + 42] = keyId.charCodeAt(i)
}
for(let i = 0; i < authUid.length; i++) {
conentArray[i + 82] = authUid.charCodeAt(i)
}
conentArray.set(this.timestampToArray(nowTime), 102)
conentArray[106] = 16
const md5Array = this.md5Encrypte(authUid + keyId, conentArray.slice(102, 106), this.currentLockInfo.publicKey)
conentArray.set(md5Array, 107)
const cebArray = sm4.encrypt(conentArray, conentArray.slice(2, 18), { mode: 'ecb', output: 'array' })
const packageArray = this.createPackageEnd(headArray, cebArray)
await this.writeBLECharacteristicValue(packageArray)
return this.getWriteResult()
},
// md5加密
md5Encrypte(text, token, key) {
const length = text.length + 4 + 16
const md5Array = new Uint8Array(length)
for (let i = 0; i < text.length; i++) {
md5Array[i] = text.charCodeAt(i)
}
md5Array.set(token , text.length)
md5Array.set(key, text.length + 4)
const md5Text= md5(md5Array)
return new Uint8Array(md5Text.match(/.{1,2}/g).map(byte => parseInt(byte, 16)))
},
// 获取锁状态
async getLockStatus(data) {
// 确认蓝牙状态正常
if(this.bluetoothStatus !== 0) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
return {
code: -1
}
}
// 确认设备连接正常
if(!this.currentLockInfo.connected) {
const srerchResult = await this.searchAndConnectDevice()
if(srerchResult.code !== 0) {
return srerchResult
}
this.updateCurrentLockInfo({
...this.currentLockInfo,
deviceId: srerchResult.data.deviceId
})
console.log('设备ID', this.currentLockInfo.deviceId)
const result = await this.connectBluetoothDevice()
console.log('连接结果', result)
if(!result) {
return {
code: -1
}
}
}
const { name, uid, nowTime, localTime } = data
const length = 2 + 40 + 20 + 4 + 4
const headArray = this.createPackageHeader(3, length)
const conentArray = new Uint8Array(length)
conentArray[0] = cmdIds.getLockStatus / 256
conentArray[1] = cmdIds.getLockStatus % 256
for (let i = 0; i < name.length; i++) {
conentArray[i + 2] = name.charCodeAt(i)
}
for (let i = 0; i < uid.length; i++) {
conentArray[i + 42] = uid.charCodeAt(i)
}
conentArray.set(this.timestampToArray(nowTime), 62)
conentArray.set(this.timestampToArray(localTime), 66)
const cebArray = sm4.encrypt(conentArray, this.currentLockInfo.commKey, { mode: 'ecb', output: 'array' })
const packageArray = this.createPackageEnd(headArray, cebArray)
await this.writeBLECharacteristicValue(packageArray)
return this.getWriteResult(this.getLockStatus, data)
},
// 时间戳转二进制
timestampToArray(timestamp) {
const array = new Uint8Array(4)
array[0] = (timestamp & 0xff000000) >> 24
array[1] = (timestamp & 0xff0000) >> 16
array[2] = (timestamp & 0xff00) >> 8
array[3] = (timestamp & 0xff)
return array
},
// 二进制转时间戳
arrayToTimestamp(array) {
const timestamp = (array[0] << 24) | (array[1] << 16) | (array[2] << 8) | array[3]
return timestamp >>> 0
},
// 添加用户
async addLockUser(data) {
// 确认蓝牙状态正常
if(this.bluetoothStatus !== 0) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
return {
code: -1
}
}
// 确认设备连接正常
if(!this.currentLockInfo.connected) {
const srerchResult = await this.searchAndConnectDevice()
if(srerchResult.code !== 0) {
return srerchResult
}
this.updateCurrentLockInfo({
...this.currentLockInfo,
deviceId: srerchResult.data.deviceId
})
console.log('设备ID', this.currentLockInfo.deviceId)
const result = await this.connectBluetoothDevice()
console.log('连接结果', result)
if(!result) {
return {
code: -1
}
}
}
const { name, authUid, uid, keyId, openMode, keyType, startDate, expireDate, useCountLimit, isRound, weekRound,
startHour, startMin, endHour, endMin, role, password } = data
const length = 2 + 40 + 20 + 40 + 20 + 1 + 1 + 4 + 4 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 20 + 4 + 1 + 16
const headArray = this.createPackageHeader(3, length)
const conentArray = new Uint8Array(length)
conentArray[0] = cmdIds.addUser / 256
conentArray[1] = cmdIds.addUser % 256
for(let i = 0; i < name.length; i++) {
conentArray[i + 2] = name.charCodeAt(i)
}
for(let i = 0; i < authUid.length; i++) {
conentArray[i + 42] = authUid.charCodeAt(i)
}
for(let i = 0; i < keyId.length; i++) {
conentArray[i + 62] = keyId.charCodeAt(i)
}
for(let i = 0; i < uid.length; i++) {
conentArray[i + 102] = uid.charCodeAt(i)
}
conentArray[122] = openMode
conentArray[123] = keyType
conentArray.set(this.timestampToArray(startDate), 124)
conentArray.set(this.timestampToArray(expireDate), 128)
conentArray[132] = useCountLimit / 256
conentArray[133] = useCountLimit % 256
conentArray[134] = isRound
conentArray[135] = weekRound
conentArray[136] = startHour
conentArray[137] = startMin
conentArray[138] = endHour
conentArray[139] = endMin
conentArray[140] = role
for(let i = 0; i < password.length; i++) {
conentArray[i + 141] = password.charCodeAt(i)
}
conentArray.set(this.currentLockInfo.token || this.timestampToArray(startDate), 161)
conentArray[165] = 16
const md5Array = this.md5Encrypte(authUid + keyId, this.currentLockInfo.token || this.timestampToArray(startDate), this.currentLockInfo.publicKey)
conentArray.set(md5Array, 166)
const cebArray = sm4.encrypt(conentArray, this.currentLockInfo.commKey, { mode: 'ecb', output: 'array' })
const packageArray = this.createPackageEnd(headArray, cebArray)
await this.writeBLECharacteristicValue(packageArray, false)
return this.getWriteResult(this.addLockUser, data)
},
// 获取写入结果
getWriteResult(request, params) {
const that = this
return new Promise(resolve => {
const getWriteResultTimer = setTimeout(() => {
resolve({ code: -1 })
}, 20000)
characteristicValueCallback = async (data) => {
// code 6 token过期,重新获取
if(data.code === 6) {
resolve(await request(params))
} else if(data.code === 4) {
const checkResult = await that.checkLockUser(true)
if(checkResult) {
resolve(await request(params))
} else {
clearTimeout(getWriteResultTimer)
resolve(data)
}
} else {
clearTimeout(getWriteResultTimer)
resolve(data)
}
}
})
},
// 开门
async openDoor(data) {
// 确认蓝牙状态正常
if(this.bluetoothStatus !== 0) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
return {
code: -1
}
}
// 确认设备连接正常
if(!this.currentLockInfo.connected) {
const srerchResult = await this.searchAndConnectDevice()
if(srerchResult.code !== 0) {
return srerchResult
}
this.updateCurrentLockInfo({
...this.currentLockInfo,
deviceId: srerchResult.data.deviceId
})
console.log('设备ID', this.currentLockInfo.deviceId)
const result = await this.connectBluetoothDevice()
console.log('连接结果', result)
if(!result) {
return {
code: -1
}
}
}
// 检查是否已添加为用户
const checkResult = await this.checkLockUser()
if (!checkResult) {
return {
code: -1
}
}
const { name, uid, openMode, openTime, onlineToken } = data
const length = 2 + 40 + 20 + 1 + 4 + 4 + 1 + 16 + 16
const headArray = this.createPackageHeader(3, length)
const conentArray = new Uint8Array(length)
conentArray[0] = cmdIds.openDoor / 256
conentArray[1] = cmdIds.openDoor % 256
for(let i = 0; i < name.length; i++) {
conentArray[i + 2] = name.charCodeAt(i)
}
for (let i = 0; i < uid.length; i++) {
conentArray[i + 42] = uid.charCodeAt(i)
}
conentArray[62] = openMode
conentArray.set(this.timestampToArray(openTime), 63)
console.log('开门时token', this.currentLockInfo.token)
conentArray.set(this.currentLockInfo.token || this.timestampToArray(openTime), 67)
conentArray[71] = 16
const md5Array = this.md5Encrypte(name + uid, this.currentLockInfo.token || this.timestampToArray(openTime), this.currentLockInfo.signKey)
conentArray.set(md5Array, 72)
for (let i = 0; i < onlineToken.length; i++) {
conentArray[i + 88] = onlineToken.charCodeAt(i)
}
const cebArray = sm4.encrypt(conentArray, this.currentLockInfo.commKey, { mode: 'ecb', output: 'array' })
const packageArray = this.createPackageEnd(headArray, cebArray)
this.writeBLECharacteristicValue(packageArray)
return this.getWriteResult(this.openDoor, data)
},
// 清理用户
async cleanLockUser(data) {
// 确认蓝牙状态正常
if(this.bluetoothStatus !== 0) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
return {
code: -1
}
}
// 确认设备连接正常
if(!this.currentLockInfo.connected) {
const srerchResult = await this.searchAndConnectDevice()
if(srerchResult.code !== 0) {
return srerchResult
}
this.updateCurrentLockInfo({
...this.currentLockInfo,
deviceId: srerchResult.data.deviceId
})
console.log('设备ID', this.currentLockInfo.deviceId)
const result = await this.connectBluetoothDevice()
console.log('连接结果', result)
if(!result) {
return {
code: -1
}
}
}
const { name, authUid, keyId, uid, userNoList } = data
const length = 2 + 40 + 20 + 40 + 20 + 2 + userNoList.length + 4 + 1 + 16
const headArray = this.createPackageHeader(3, length)
const conentArray = new Uint8Array(length)
conentArray[0] = cmdIds.cleanUser / 256
conentArray[1] = cmdIds.cleanUser % 256
for (let i = 0; i < name.length; i++) {
conentArray[i + 2] = name.charCodeAt(i)
}
for (let i = 0; i < authUid.length; i++) {
conentArray[i + 42] = authUid.charCodeAt(i)
}
for (let i = 0; i < keyId.length; i++) {
conentArray[i + 62] = keyId.charCodeAt(i)
}
for (let i = 0; i < uid.length; i++) {
conentArray[i + 102] = uid.charCodeAt(i)
}
conentArray[122] = userNoList.length / 256
conentArray[123] = userNoList.length % 256
for (let i = 0; i < userNoList.length; i++) {
conentArray[i + 124] = userNoList[i]
}
conentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 124 + userNoList.length)
conentArray[128 + userNoList.length] = 16
const md5Array = this.md5Encrypte(authUid + keyId, this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), this.currentLockInfo.publicKey)
conentArray.set(md5Array, 129 + userNoList.length)
const cebArray = sm4.encrypt(conentArray, this.currentLockInfo.commKey, { mode: 'ecb', output: 'array' })
const packageArray = this.createPackageEnd(headArray, cebArray)
await this.writeBLECharacteristicValue(packageArray)
return this.getWriteResult(this.cleanLockUser, data)
},
// 恢复出厂设置
async resetDevice(data) {
// 确认蓝牙状态正常
if(this.bluetoothStatus !== 0) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
return {
code: -1
}
}
// 确认设备连接正常
if(!this.currentLockInfo.connected) {
const srerchResult = await this.searchAndConnectDevice()
if(srerchResult.code !== 0) {
return srerchResult
}
this.updateCurrentLockInfo({
...this.currentLockInfo,
deviceId: srerchResult.data.deviceId
})
console.log('设备ID', this.currentLockInfo.deviceId)
const result = await this.connectBluetoothDevice()
console.log('连接结果', result)
if(!result) {
return {
code: -1
}
}
}
// 检查是否已添加为用户
const checkResult = await this.checkLockUser()
if (!checkResult) {
return {
code: -1
}
}
const { name, authUid, keyId } = data
const length = 2 + 40 + 20 + 4 + 1 + 16
const headArray = this.createPackageHeader(3, length)
const conentArray = new Uint8Array(length)
conentArray[0] = cmdIds.resetDevice / 256
conentArray[1] = cmdIds.resetDevice % 256
for(let i = 0; i < name.length; i++) {
conentArray[i + 2] = name.charCodeAt(i)
}
for(let i = 0; i < authUid.length; i++) {
conentArray[i + 42] = authUid.charCodeAt(i)
}
conentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 62)
conentArray[66] = 16
const md5Array = this.md5Encrypte(name, this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), this.currentLockInfo.publicKey)
conentArray.set(md5Array, 67)
const cebArray = sm4.encrypt(conentArray, this.currentLockInfo.commKey, { mode: 'ecb', output: 'array' })
const packageArray = this.createPackageEnd(headArray, cebArray)
await this.writeBLECharacteristicValue(packageArray)
return this.getWriteResult(this.resetDevice, data)
},
// 重置开锁密码
async resetLockPassword(data) {
// 确认蓝牙状态正常
if(this.bluetoothStatus !== 0) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
return {
code: -1
}
}
// 确认设备连接正常
if(!this.currentLockInfo.connected) {
const srerchResult = await this.searchAndConnectDevice()
if(srerchResult.code !== 0) {
return srerchResult
}
this.updateCurrentLockInfo({
...this.currentLockInfo,
deviceId: srerchResult.data.deviceId
})
console.log('设备ID', this.currentLockInfo.deviceId)
const result = await this.connectBluetoothDevice()
console.log('连接结果', result)
if(!result) {
return {
code: -1
}
}
}
// 检查是否已添加为用户
const checkResult = await this.checkLockUser()
if (!checkResult) {
return {
code: -1
}
}
const { keyId, uid } = data
const length = 2 + 1 + 1 + 40 + 20 + 4 + 1 + 16
const headArray = this.createPackageHeader(3, length)
const conentArray = new Uint8Array(length)
conentArray[0] = cmdIds.expandCmd / 256
conentArray[1] = cmdIds.expandCmd % 256
// 子命令
conentArray[2] = subCmdIds.resetLockPassword
conentArray[3] = length - 4
for (let i = 0; i < keyId.length; i++) {
conentArray[i + 4] = keyId.charCodeAt(i)
}
for (let i = 0; i < uid.length; i++) {
conentArray[i + 44] = uid.charCodeAt(i)
}
conentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 64)
conentArray[68] = 16
const md5Array = this.md5Encrypte(keyId + uid, this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), this.currentLockInfo.signKey)
conentArray.set(md5Array, 69)
const cebArray = sm4.encrypt(conentArray, this.currentLockInfo.commKey, { mode: 'ecb', output: 'array' })
const packageArray = this.createPackageEnd(headArray, cebArray)
await this.writeBLECharacteristicValue(packageArray)
return this.getWriteResult(this.resetLockPassword, data)
},
// 设置密码
async setLockPassword(data) {
// 确认蓝牙状态正常
if(this.bluetoothStatus !== 0) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
return {
code: -1
}
}
// 确认设备连接正常
if(!this.currentLockInfo.connected) {
const srerchResult = await this.searchAndConnectDevice()
if(srerchResult.code !== 0) {
return srerchResult
}
this.updateCurrentLockInfo({
...this.currentLockInfo,
deviceId: srerchResult.data.deviceId
})
console.log('设备ID', this.currentLockInfo.deviceId)
const result = await this.connectBluetoothDevice()
console.log('连接结果', result)
if(!result) {
return {
code: -1
}
}
}
// 检查是否已添加为用户
const checkResult = await this.checkLockUser()
if (!checkResult) {
return {
code: -1
}
}
const { keyId, uid, pwdNo, operate, isAdmin, pwd, userCountLimit, startTime, endTime} = data
const length = 2 + 1 + 1 + 40 + 20 + 2 + 1 + 1 + 20 + 2 + 4 + 4 + 4 + 1 + 16
const headArray = this.createPackageHeader(3, length)
const conentArray = new Uint8Array(length)
conentArray[0] = cmdIds.expandCmd / 256
conentArray[1] = cmdIds.expandCmd % 256
// 子命令
conentArray[2] = subCmdIds.setLockPassword
conentArray[3] = length - 3
for (let i = 0; i < keyId.length; i++) {
conentArray[i + 4] = keyId.charCodeAt(i)
}
for (let i = 0; i < uid.length; i++) {
conentArray[i + 44] = uid.charCodeAt(i)
}
conentArray[64] = pwdNo / 256
conentArray[65] = pwdNo % 256
conentArray[66] = operate
conentArray[67] = isAdmin
for (let i = 0; i < pwd.length; i++) {
conentArray[i + 68] = pwd.charCodeAt(i)
}
conentArray[88] = userCountLimit / 256
conentArray[89] = userCountLimit % 256
conentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 90)
conentArray.set(this.timestampToArray(startTime), 94)
conentArray.set(this.timestampToArray(endTime), 98)
conentArray[102] = 16
const md5Array = this.md5Encrypte(keyId + uid, this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), this.currentLockInfo.signKey)
conentArray.set(md5Array, 103)
const cebArray = sm4.encrypt(conentArray, this.currentLockInfo.commKey, { mode: 'ecb', output: 'array' })
const packageArray = this.createPackageEnd(headArray, cebArray)
await this.writeBLECharacteristicValue(packageArray)
return this.getWriteResult(this.setLockPassword, data)
}
}
})