完成获取公钥和获取私钥功能的写入和解析
This commit is contained in:
parent
5b6ee58df3
commit
51c8d77489
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<view>
|
<view>
|
||||||
<button @click="getList">获取设备列表</button>
|
<button class="button" @click="getList">获取设备列表</button>
|
||||||
<view v-if="showList">
|
<view v-if="showList">
|
||||||
<button class="device" v-for="item in list"
|
<button class="device" v-for="item in list"
|
||||||
:key="item.deviceId" @click="connect(item)">{{item.name}}
|
:key="item.deviceId" @click="connect(item)">{{item.name}}
|
||||||
@ -903,4 +903,8 @@ export default {
|
|||||||
.device {
|
.device {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin-top: 200rpx;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -6,9 +6,10 @@
|
|||||||
<view class="device-list" v-for="(item, index) in deviceList" :key="item.deviceId" @click="connect(item)">{{item.name}}</view>
|
<view class="device-list" v-for="(item, index) in deviceList" :key="item.deviceId" @click="connect(item)">{{item.name}}</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-else>
|
<view v-else>
|
||||||
<button class="button">获取公钥</button>
|
<button class="button" @click="bindUser">添加用户</button>
|
||||||
<button class="button">获取私钥</button>
|
<button class="button">开门</button>
|
||||||
<button class="button">添加用户</button>
|
<button class="button">关门</button>
|
||||||
|
<button class="button" @click="getLockStatusResult">获取锁状态</button>
|
||||||
<view>名称:{{currentLockInfo.name}}</view>
|
<view>名称:{{currentLockInfo.name}}</view>
|
||||||
<view>设备Id:{{currentLockInfo.deviceId}}</view>
|
<view>设备Id:{{currentLockInfo.deviceId}}</view>
|
||||||
<view v-if="currentLockInfo.serviceId">服务:{{currentLockInfo.serviceId}}</view>
|
<view v-if="currentLockInfo.serviceId">服务:{{currentLockInfo.serviceId}}</view>
|
||||||
@ -26,16 +27,18 @@
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
showAdd: true,
|
showAdd: true,
|
||||||
showConnect: false
|
showConnect: false,
|
||||||
|
keyId: '0',
|
||||||
|
authUid: '294'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(useBluetoothStore, ['deviceList', 'currentLockInfo'])
|
...mapState(useBluetoothStore, ['deviceList', 'currentLockInfo'])
|
||||||
},
|
},
|
||||||
async onLoad () {},
|
onLoad () {},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(useBluetoothStore, ['getBluetoothDevices', 'stopGetBluetoothDevices', 'updateCurrentLockInfo',
|
...mapActions(useBluetoothStore, ['getBluetoothDevices', 'stopGetBluetoothDevices', 'updateCurrentLockInfo',
|
||||||
'connectBluetoothDevice']),
|
'connectBluetoothDevice', 'getPublicKey', 'getCommKey', 'getLockStatus', 'addLockUser']),
|
||||||
getList() {
|
getList() {
|
||||||
this.getBluetoothDevices()
|
this.getBluetoothDevices()
|
||||||
this.showAdd = false
|
this.showAdd = false
|
||||||
@ -54,6 +57,45 @@
|
|||||||
this.showConnect = true
|
this.showConnect = true
|
||||||
this.stopGetBluetoothDevices()
|
this.stopGetBluetoothDevices()
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
async bindUser() {
|
||||||
|
const { code } = await this.getPublicKey(this.currentLockInfo.name)
|
||||||
|
console.log('获取公钥返回', code)
|
||||||
|
if(code !== 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { code: getCommKeyCode } = await this.getCommKey(this.currentLockInfo.name, this.keyId, this.authUid,
|
||||||
|
parseInt(new Date().getTime() / 1000), this.currentLockInfo.publicKey)
|
||||||
|
console.log('获取私钥返回', getCommKeyCode)
|
||||||
|
if(getCommKeyCode !== 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// this.addLockUser({
|
||||||
|
// name: this.currentLockInfo.name,
|
||||||
|
// keyId: this.keyId,
|
||||||
|
// authUid: this.authUid,
|
||||||
|
// uid: this.authUid,
|
||||||
|
// publicKey: this.currentLockInfo.publicKey,
|
||||||
|
// openMode: 1,
|
||||||
|
// keyType: 1,
|
||||||
|
// startDate: parseInt(new Date().getTime() / 1000),
|
||||||
|
// expireDate: 0xffffffff,
|
||||||
|
// useCountLimit: 0xffff,
|
||||||
|
// isRound: 0,
|
||||||
|
// weekRound: 0,
|
||||||
|
// startHour: 0,
|
||||||
|
// startMin: 0,
|
||||||
|
// endHour: 0,
|
||||||
|
// endMin: 0,
|
||||||
|
// role: 0xff,
|
||||||
|
// token: this.currentLockInfo.token || new Uint8Array([0,0,0,0]),
|
||||||
|
// password: (Math.floor(Math.random() * 900000) + 100000).toString()
|
||||||
|
// })
|
||||||
|
},
|
||||||
|
getLockStatusResult() {
|
||||||
|
const timnestamp = parseInt(new Date().getTime() / 1000)
|
||||||
|
this.getLockStatus(this.currentLockInfo.name, this.authUid,timnestamp, timnestamp,
|
||||||
|
this.currentLockInfo.commKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,9 +2,32 @@
|
|||||||
* @description 蓝牙数据持久化
|
* @description 蓝牙数据持久化
|
||||||
*/
|
*/
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
import crc from 'crc'
|
||||||
|
import { sm4 } from 'sm-crypto'
|
||||||
|
import { md5 } from 'js-md5'
|
||||||
|
|
||||||
// 定时器
|
// 定时器
|
||||||
let timer
|
let timer
|
||||||
|
// 特性值回调
|
||||||
|
let characteristicValueCallback = null
|
||||||
|
|
||||||
|
// 命令ID
|
||||||
|
const cmdIds = {
|
||||||
|
// 获取公钥
|
||||||
|
getPublicKey: 0x3090,
|
||||||
|
// 获取私钥
|
||||||
|
getCommKey: 0x3091,
|
||||||
|
// 获取锁状态
|
||||||
|
getLockStatus: 0x3040,
|
||||||
|
// 新增用户
|
||||||
|
addUser: 0x3001,
|
||||||
|
// 开门
|
||||||
|
openDoor: 0x3005,
|
||||||
|
// 重置设备
|
||||||
|
resetDevice: 0x3004,
|
||||||
|
// 清理用户
|
||||||
|
cleanUser: 0x300C,
|
||||||
|
}
|
||||||
|
|
||||||
export const useBluetoothStore = defineStore('ble', {
|
export const useBluetoothStore = defineStore('ble', {
|
||||||
state() {
|
state() {
|
||||||
@ -21,7 +44,9 @@ export const useBluetoothStore = defineStore('ble', {
|
|||||||
// 设备列表
|
// 设备列表
|
||||||
deviceList: [],
|
deviceList: [],
|
||||||
// 当前锁信息
|
// 当前锁信息
|
||||||
currentLockInfo: {}
|
currentLockInfo: {},
|
||||||
|
// 消息序号
|
||||||
|
messageCount: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
@ -94,12 +119,99 @@ export const useBluetoothStore = defineStore('ble', {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
// 解析特征值
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
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]
|
||||||
|
if(cmdId === cmdIds.getLockStatus) {
|
||||||
|
if (decrypted[2] === 0) {
|
||||||
|
console.log('获取锁状态成功', decrypted)
|
||||||
|
}
|
||||||
|
} else if(cmdId === cmdIds.openDoor) {
|
||||||
|
if (decrypted[2] === 0) {
|
||||||
|
console.log('开门成功', decrypted)
|
||||||
|
}
|
||||||
|
} else if(cmdId === cmdIds.addUser) {
|
||||||
|
if (decrypted[2] === 0) {
|
||||||
|
console.log('添加用户', decrypted)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
// 监听蓝牙设备特征值改变
|
// 监听蓝牙设备特征值改变
|
||||||
onBluetoothCharacteristicValueChange() {
|
onBluetoothCharacteristicValueChange() {
|
||||||
const that = this
|
const that = this
|
||||||
|
// 完整数据
|
||||||
|
let completeArray
|
||||||
|
// 完整内容数据长度
|
||||||
|
let length
|
||||||
|
console.log('开始监听特征值改变')
|
||||||
uni.onBLECharacteristicValueChange(function (res) {
|
uni.onBLECharacteristicValueChange(function (res) {
|
||||||
// 待完善
|
if(res.deviceId === that.currentLockInfo.deviceId) {
|
||||||
console.log('特征值改变', res)
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 开始搜索蓝牙设备
|
// 开始搜索蓝牙设备
|
||||||
@ -149,8 +261,8 @@ export const useBluetoothStore = defineStore('ble', {
|
|||||||
}
|
}
|
||||||
console.log('设备列表', that.deviceList)
|
console.log('设备列表', that.deviceList)
|
||||||
},
|
},
|
||||||
fail: async function (err) {
|
fail: async function (res) {
|
||||||
console.log('获取设备列表失败', err)
|
console.log('获取设备列表失败', res)
|
||||||
if(res.errCode === 10000) {
|
if(res.errCode === 10000) {
|
||||||
// 重新初始化蓝牙适配器
|
// 重新初始化蓝牙适配器
|
||||||
await that.initBluetooth()
|
await that.initBluetooth()
|
||||||
@ -312,7 +424,7 @@ export const useBluetoothStore = defineStore('ble', {
|
|||||||
deviceId: that.currentLockInfo.deviceId,
|
deviceId: that.currentLockInfo.deviceId,
|
||||||
serviceId: that.currentLockInfo.serviceId,
|
serviceId: that.currentLockInfo.serviceId,
|
||||||
characteristicId: that.currentLockInfo.notifyCharacteristicId,
|
characteristicId: that.currentLockInfo.notifyCharacteristicId,
|
||||||
success() {
|
success(res) {
|
||||||
console.log('订阅成功', res)
|
console.log('订阅成功', res)
|
||||||
},
|
},
|
||||||
fail(res) {
|
fail(res) {
|
||||||
@ -320,30 +432,6 @@ export const useBluetoothStore = defineStore('ble', {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 重新连接设备
|
|
||||||
reconnectDevice() {
|
|
||||||
const that = this
|
|
||||||
return new Promise(async resolve => {
|
|
||||||
uni.createBLEConnection({
|
|
||||||
deviceId: that.currentLockInfo.deviceId,
|
|
||||||
success (res) {
|
|
||||||
console.log('重连成功', res)
|
|
||||||
that.notifyBluetoothCharacteristicValueChange()
|
|
||||||
resolve(true)
|
|
||||||
},
|
|
||||||
fail(res) {
|
|
||||||
console.log('重连失败', res)
|
|
||||||
uni.showModal({
|
|
||||||
title: '提示',
|
|
||||||
content: '设备连接已断开,请靠近设备并保持设备处于唤醒状态',
|
|
||||||
showCancel: false,
|
|
||||||
confirmText: '确定'
|
|
||||||
})
|
|
||||||
resolve(false)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 断开蓝牙连接
|
// 断开蓝牙连接
|
||||||
closeBluetoothConnection() {
|
closeBluetoothConnection() {
|
||||||
const that = this
|
const that = this
|
||||||
@ -370,7 +458,7 @@ export const useBluetoothStore = defineStore('ble', {
|
|||||||
|
|
||||||
// 确认设备连接正常
|
// 确认设备连接正常
|
||||||
if(!that.currentLockInfo.connected) {
|
if(!that.currentLockInfo.connected) {
|
||||||
const result = await that.reconnectDevice()
|
const result = await that.connectBluetoothDevice()
|
||||||
if(!result) return
|
if(!result) return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,21 +471,219 @@ export const useBluetoothStore = defineStore('ble', {
|
|||||||
// 次数
|
// 次数
|
||||||
const count = Math.ceil(binaryData.length / 20)
|
const count = Math.ceil(binaryData.length / 20)
|
||||||
for(let i = 0; i < count; i++) {
|
for(let i = 0; i < count; i++) {
|
||||||
const writeData = binaryData.slice(i * 20, i === (count - 1) ? binaryData.length - 1 : (i + 1) * 20)
|
const writeData = binaryData.slice(i * 20, i === (count - 1) ? binaryData.length : (i + 1) * 20)
|
||||||
|
|
||||||
uni.writeBLECharacteristicValue({
|
uni.writeBLECharacteristicValue({
|
||||||
deviceId: that.currentLockInfo.deviceId,
|
deviceId: that.currentLockInfo.deviceId,
|
||||||
serviceId: that.currentLockInfo.serviceId,
|
serviceId: that.currentLockInfo.serviceId,
|
||||||
characteristicId: that.currentLockInfo.writeCharacteristicId,
|
characteristicId: that.currentLockInfo.writeCharacteristicId,
|
||||||
value: writeData,
|
value: writeData.buffer,
|
||||||
success() {
|
success() {
|
||||||
console.log('数据写入成功')
|
console.log('数据写入成功', Array.from(writeData))
|
||||||
},
|
},
|
||||||
fail(res) {
|
fail(res) {
|
||||||
console.log('写入失败', res)
|
console.log('写入失败', res)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
* 生成包头
|
||||||
|
* encryptionType 加密类型 0:明文,1:AES128,2:SM4(事先约定密钥),3:SM4(设备指定密钥)
|
||||||
|
* 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) {
|
||||||
|
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, publicKey) {
|
||||||
|
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.platformMd5Encrypte(authUid, keyId, conentArray.slice(102, 106), 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加密
|
||||||
|
* authUid
|
||||||
|
* keyId
|
||||||
|
* token | nowTime
|
||||||
|
* publicKey
|
||||||
|
* */
|
||||||
|
platformMd5Encrypte(authUid, keyId, token, publicKey) {
|
||||||
|
const length = authUid.length + keyId.length + 4 + 16
|
||||||
|
const md5Array = new Uint8Array(length)
|
||||||
|
|
||||||
|
for (let i = 0; i < authUid.length; i++) {
|
||||||
|
md5Array[i] = authUid.charCodeAt(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < keyId.length; i++) {
|
||||||
|
md5Array[authUid.length + i] = keyId.charCodeAt(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
md5Array.set(token, authUid.length + keyId.length)
|
||||||
|
md5Array.set(publicKey, authUid.length + keyId.length + 4)
|
||||||
|
|
||||||
|
const md5Text= md5(md5Array)
|
||||||
|
return new Uint8Array(md5Text.match(/.{1,2}/g).map(byte => parseInt(byte, 16)))
|
||||||
|
},
|
||||||
|
// 获取锁状态
|
||||||
|
async getLockStatus(name, uid, nowTime, localTime, commKey) {
|
||||||
|
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, commKey, { mode: 'ecb', output: 'array' })
|
||||||
|
|
||||||
|
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||||
|
|
||||||
|
await this.writeBLECharacteristicValue(packageArray)
|
||||||
|
},
|
||||||
|
// 时间戳转二进制
|
||||||
|
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
|
||||||
|
},
|
||||||
|
// 添加用户
|
||||||
|
addLockUser(data) {
|
||||||
|
const { name, authUid, uid, keyId, openMode, keyType, startDate, expireDate, useCountLimit, isRound, weekRound,
|
||||||
|
startHour, startMin, endHour, endMin, role, password, token, publicKey} = 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
|
||||||
|
|
||||||
|
// 尚未完成
|
||||||
|
},
|
||||||
|
// 获取写入结果
|
||||||
|
getWriteResult() {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
resolve({ code: -1 })
|
||||||
|
}, 7000)
|
||||||
|
characteristicValueCallback = (data) => {
|
||||||
|
clearTimeout(timer)
|
||||||
|
resolve(data)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user