完成添加用户、开门、恢复出厂设置、获取锁状态的写入与封装

This commit is contained in:
范鹏 2024-08-16 11:51:27 +08:00
parent 51c8d77489
commit 1130b198b9
2 changed files with 267 additions and 75 deletions

View File

@ -7,14 +7,12 @@
</view>
<view v-else>
<button class="button" @click="bindUser">添加用户</button>
<button class="button">开门</button>
<button class="button">关门</button>
<button class="button" @click="openDoorOperate">开门</button>
<button class="button" @click="closeDoorOperate">关门</button>
<button class="button" @click="reset">恢复出厂设置</button>
<button class="button" @click="getLockStatusResult">获取锁状态</button>
<view>名称{{currentLockInfo.name}}</view>
<view>设备Id{{currentLockInfo.deviceId}}</view>
<view v-if="currentLockInfo.serviceId">服务{{currentLockInfo.serviceId}}</view>
<view v-if="currentLockInfo.writeCharacteristicId">写入特征值Id{{currentLockInfo.writeCharacteristicId}}</view>
<view v-if="currentLockInfo.notifyCharacteristicId">监听特征值Id{{currentLockInfo.notifyCharacteristicId}}</view>
</view>
</view>
</template>
@ -29,7 +27,8 @@
showAdd: true,
showConnect: false,
keyId: '0',
authUid: '294'
authUid: '294',
onlineToken: '0'
}
},
computed: {
@ -38,7 +37,36 @@
onLoad () {},
methods: {
...mapActions(useBluetoothStore, ['getBluetoothDevices', 'stopGetBluetoothDevices', 'updateCurrentLockInfo',
'connectBluetoothDevice', 'getPublicKey', 'getCommKey', 'getLockStatus', 'addLockUser']),
'connectBluetoothDevice', 'getPublicKey', 'getCommKey', 'getLockStatus', 'addLockUser', 'timestampToArray',
'openDoor', 'resetDevice']),
async openDoorOperate() {
const { code } = await this.openDoor({
name: this.currentLockInfo.name,
uid: this.authUid,
openMode: 0,
openTime: parseInt(new Date().getTime() / 1000),
onlineToken: this.onlineToken
})
console.log('开门返回', code)
},
async closeDoorOperate() {
const { code } = await this.openDoor({
name: this.currentLockInfo.name,
uid: this.authUid,
openMode: 32,
openTime: parseInt(new Date().getTime() / 1000),
onlineToken: this.onlineToken
})
console.log('关门返回', code)
},
async reset() {
const { code } = await this.resetDevice({
name: this.currentLockInfo.name,
authUid: this.authUid,
keyId: this.keyId
})
console.log('恢复出厂设置返回', code)
},
getList() {
this.getBluetoothDevices()
this.showAdd = false
@ -65,37 +93,43 @@
return
}
const { code: getCommKeyCode } = await this.getCommKey(this.currentLockInfo.name, this.keyId, this.authUid,
parseInt(new Date().getTime() / 1000), this.currentLockInfo.publicKey)
parseInt(new Date().getTime() / 1000))
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()
// })
const timestamp = parseInt(new Date().getTime() / 1000)
const { code: addUserCode } = await this.addLockUser({
name: this.currentLockInfo.name,
keyId: this.keyId,
authUid: this.authUid,
uid: this.authUid,
publicKey: this.currentLockInfo.publicKey,
commKey: this.currentLockInfo.commKey,
openMode: 1,
keyType: 1,
startDate: timestamp,
expireDate: 0xffffffff,
useCountLimit: 0xffff,
isRound: 0,
weekRound: 0,
startHour: 0,
startMin: 0,
endHour: 0,
endMin: 0,
role: 0xff,
password: (Math.floor(Math.random() * 900000) + 100000).toString()
})
console.log('添加用户返回', addUserCode)
},
getLockStatusResult() {
const timnestamp = parseInt(new Date().getTime() / 1000)
this.getLockStatus(this.currentLockInfo.name, this.authUid,timnestamp, timnestamp,
this.currentLockInfo.commKey)
this.getLockStatus({
name: this.currentLockInfo.name,
uid: this.authUid,
nowTime: timnestamp,
localTime: timnestamp
})
}
}
}

View File

@ -166,18 +166,59 @@ export const useBluetoothStore = defineStore('ble', {
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)
}
switch (cmdId) {
case cmdIds.getLockStatus:
if (decrypted[2] === 0) {
const lockConfig = {
vendor: decrypted.slice(3, 23),
product: decrypted[23],
model: decrypted.slice(24, 44),
fwVersion: decrypted.slice(44, 64),
hwVersion: decrypted.slice(64, 84),
serialNum0: decrypted.slice(84, 100),
serialNum1: decrypted.slice(100, 116),
btDeviceName: decrypted.slice(116, 132),
battRemCap: decrypted[132],
battRemCapStandby: decrypted[133],
restoreCounter: decrypted.slice(134, 136),
restoreDate: decrypted.slice(136, 140),
icPartNo: decrypted.slice(140, 150),
inDate: decrypted.slice(150, 154),
mac: decrypted.slice(154, 174),
featurevalueLength: decrypted[174],
featureValue: decrypted.slice(175, 175 + decrypted[174]),
featureEnValLength: decrypted[175 + decrypted[174]],
featureEnVal: decrypted.slice(176 + decrypted[174], 176 + decrypted[174] + decrypted[175 + decrypted[174]]),
}
that.updateCurrentLockInfo({
...that.currentLockInfo,
lockConfig
})
console.log('获取锁状态成功', that.currentLockInfo.lockConfig)
}
characteristicValueCallback({
code: decrypted[2]
})
break
case cmdIds.addUser:
that.updateCurrentLockInfo({
...that.currentLockInfo,
token: decrypted.slice(42,46)
})
characteristicValueCallback({
code: decrypted[46]
})
break
default:
that.updateCurrentLockInfo({
...that.currentLockInfo,
token: decrypted.slice(2,6)
})
characteristicValueCallback({
code: decrypted[6]
})
break
}
}
},
@ -478,9 +519,6 @@ export const useBluetoothStore = defineStore('ble', {
serviceId: that.currentLockInfo.serviceId,
characteristicId: that.currentLockInfo.writeCharacteristicId,
value: writeData.buffer,
success() {
console.log('数据写入成功', Array.from(writeData))
},
fail(res) {
console.log('写入失败', res)
}
@ -568,7 +606,7 @@ export const useBluetoothStore = defineStore('ble', {
return this.getWriteResult()
},
// 获取私钥
async getCommKey(name, keyId, authUid, nowTime, publicKey) {
async getCommKey(name, keyId, authUid, nowTime) {
const length = 2 + 40 + 40 + 20 + 4 + 1 + 16
const headArray = this.createPackageHeader(2, length)
const conentArray = new Uint8Array(length)
@ -592,7 +630,7 @@ export const useBluetoothStore = defineStore('ble', {
conentArray[106] = 16
const md5Array = this.platformMd5Encrypte(authUid, keyId, conentArray.slice(102, 106), publicKey)
const md5Array = this.md5Encrypte(authUid + keyId, conentArray.slice(102, 106), this.currentLockInfo.publicKey)
conentArray.set(md5Array, 107)
@ -603,33 +641,24 @@ export const useBluetoothStore = defineStore('ble', {
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
// md5加密
md5Encrypte(text, token, key) {
const length = text.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 < text.length; i++) {
md5Array[i] = text.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)
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(name, uid, nowTime, localTime, commKey) {
async getLockStatus(data) {
const { name, uid, nowTime, localTime } = data
const length = 2 + 40 + 20 + 4 + 4
const headArray = this.createPackageHeader(3, length)
@ -645,11 +674,13 @@ export const useBluetoothStore = defineStore('ble', {
conentArray.set(this.timestampToArray(nowTime), 62)
conentArray.set(this.timestampToArray(localTime), 66)
const cebArray = sm4.encrypt(conentArray, commKey, { mode: 'ecb', output: 'array' })
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) {
@ -661,9 +692,9 @@ export const useBluetoothStore = defineStore('ble', {
return array
},
// 添加用户
addLockUser(data) {
async addLockUser(data) {
const { name, authUid, uid, keyId, openMode, keyType, startDate, expireDate, useCountLimit, isRound, weekRound,
startHour, startMin, endHour, endMin, role, password, token, publicKey} = data
startHour, startMin, endHour, endMin, role, password, publicKey, commKey } = 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)
@ -671,19 +702,146 @@ export const useBluetoothStore = defineStore('ble', {
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, commKey, { mode: 'ecb', output: 'array' })
const packageArray = this.createPackageEnd(headArray, cebArray)
await this.writeBLECharacteristicValue(packageArray)
return this.getWriteResult(this.addLockUser, data)
},
// 获取写入结果
getWriteResult() {
getWriteResult(request, params) {
return new Promise(resolve => {
const timer = setTimeout(() => {
resolve({ code: -1 })
}, 7000)
characteristicValueCallback = (data) => {
clearTimeout(timer)
resolve(data)
}, 20000)
characteristicValueCallback = async (data) => {
// code 6 token过期,重新获取
if(data.code === 6) {
resolve(await request(params))
} else {
clearTimeout(timer)
resolve(data)
}
}
})
},
// 开门
async openDoor(data) {
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)
conentArray.set(this.currentLockInfo.token, 67)
conentArray[71] = 16
const md5Array = this.md5Encrypte(name + uid, this.currentLockInfo.token, 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)
await this.writeBLECharacteristicValue(packageArray)
return this.getWriteResult(this.openDoor, data)
},
// 恢复出厂设置
async resetDevice(data) {
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, 62)
conentArray[66] = 16
const md5Array = this.md5Encrypte(name, this.currentLockInfo.token, 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)
}
}
})