封装已基本完成删除demo
This commit is contained in:
parent
680bfd4b15
commit
e1726ddcce
@ -10,9 +10,6 @@
|
|||||||
"pages": [
|
"pages": [
|
||||||
{
|
{
|
||||||
"path": "pages/index/index"
|
"path": "pages/index/index"
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/demo/demo"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
|
|||||||
@ -1,910 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view>
|
|
||||||
<button class="button" @click="getList">获取设备列表</button>
|
|
||||||
<view v-if="showList">
|
|
||||||
<button class="device" v-for="item in list"
|
|
||||||
:key="item.deviceId" @click="connect(item)">{{item.name}}
|
|
||||||
- {{item.pair ? '已配对' : '未配对'}}-{{item.sleep ? '休眠中' :
|
|
||||||
'已唤醒'}}</button>
|
|
||||||
</view>
|
|
||||||
<view v-else>
|
|
||||||
<button @click="getPublicKey">获取锁公钥</button>
|
|
||||||
<button @click="getCommKey">获取锁私钥</button>
|
|
||||||
<button @click="getLockStatus">获取锁状态</button>
|
|
||||||
<button @click="addUser">添加用户</button>
|
|
||||||
<button @click="openDoor">开门</button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import crc from 'crc'
|
|
||||||
import { md5 } from 'js-md5'
|
|
||||||
import { sm4 } from 'sm-crypto'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
list: [],
|
|
||||||
getting: false,
|
|
||||||
deviceId: '',
|
|
||||||
serviceId: '',
|
|
||||||
characteristicId1: '',
|
|
||||||
characteristicId2: '',
|
|
||||||
lockId: '',
|
|
||||||
publicKey: new Uint8Array(16),
|
|
||||||
commKey: new Uint8Array(16),
|
|
||||||
signKey: new Uint8Array(16),
|
|
||||||
showList: true,
|
|
||||||
number: 1,
|
|
||||||
lockStatus: new Uint8Array(1),
|
|
||||||
token: new Uint8Array([0,0,0,0]),
|
|
||||||
keyId: '0',
|
|
||||||
uid: '294',
|
|
||||||
userId: '294',
|
|
||||||
// userId: '336',
|
|
||||||
password: '',
|
|
||||||
config: {},
|
|
||||||
notify: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad() {
|
|
||||||
uni.openBluetoothAdapter({
|
|
||||||
success(res) {
|
|
||||||
console.log('初始化成功')
|
|
||||||
console.log(res)
|
|
||||||
},
|
|
||||||
fail(res) {
|
|
||||||
console.log('初始化失败')
|
|
||||||
console.log(res)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onUnload() {
|
|
||||||
uni.closeBluetoothAdapter({
|
|
||||||
success(res) {
|
|
||||||
console.log('关闭蓝牙成功')
|
|
||||||
console.log(res)
|
|
||||||
},
|
|
||||||
fail(res) {
|
|
||||||
console.log('关闭蓝牙失败')
|
|
||||||
console.log(res)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 添加超级管理员
|
|
||||||
addUser() {
|
|
||||||
// 头部数据
|
|
||||||
let headArray = new Uint8Array(12)
|
|
||||||
|
|
||||||
// 固定包头
|
|
||||||
headArray[0] = 0xEF
|
|
||||||
headArray[1] = 0x01
|
|
||||||
headArray[2] = 0xEE
|
|
||||||
headArray[3] = 0x02
|
|
||||||
|
|
||||||
// 包类型 发送
|
|
||||||
headArray[4] = 0x01
|
|
||||||
|
|
||||||
// 包序号
|
|
||||||
headArray[5] = this.number / 256
|
|
||||||
headArray[6] = this.number % 256
|
|
||||||
this.number++
|
|
||||||
|
|
||||||
// 包标识
|
|
||||||
headArray[7] = 0x23
|
|
||||||
|
|
||||||
// 数据长度
|
|
||||||
headArray[8] = 192 / 256
|
|
||||||
headArray[9] = 192 % 256
|
|
||||||
headArray[10] = 182 / 256
|
|
||||||
headArray[11] = 182 % 256
|
|
||||||
|
|
||||||
// 入参
|
|
||||||
let paramsArray = new Uint8Array(182)
|
|
||||||
|
|
||||||
// 命令
|
|
||||||
paramsArray[0] = 0x3001 / 256
|
|
||||||
paramsArray[1] = 0x3001 % 256
|
|
||||||
|
|
||||||
// 锁ID
|
|
||||||
for (let i = 0; i < this.lockId.length; i++) {
|
|
||||||
paramsArray[2 + i] = this.lockId.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用户ID
|
|
||||||
for (let i = 0; i < this.uid.length; i++) {
|
|
||||||
paramsArray[42 + i] = this.uid.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// keyId
|
|
||||||
for (let i = 0; i < this.keyId.length; i++) {
|
|
||||||
paramsArray[62 + i] = this.keyId.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// userId
|
|
||||||
for (let i = 0; i < this.userId.length; i++) {
|
|
||||||
paramsArray[102 + i] = this.userId.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 开锁方式
|
|
||||||
paramsArray[122] = 0x01
|
|
||||||
|
|
||||||
// 钥匙类型
|
|
||||||
paramsArray[123] = 0x01
|
|
||||||
|
|
||||||
// 启用日期
|
|
||||||
const nowTime = parseInt(new Date().getTime() / 1000)
|
|
||||||
|
|
||||||
paramsArray[124] = (nowTime & 0xff000000) >> 24
|
|
||||||
paramsArray[125] = (nowTime & 0xff0000) >> 16
|
|
||||||
paramsArray[126] = (nowTime & 0xff00) >> 8
|
|
||||||
paramsArray[127] = (nowTime & 0xff)
|
|
||||||
|
|
||||||
// 结束日期
|
|
||||||
const endTime = 0xffffffff
|
|
||||||
|
|
||||||
paramsArray[128] = (endTime & 0xff000000) >> 24
|
|
||||||
paramsArray[129] = (endTime & 0xff0000) >> 16
|
|
||||||
paramsArray[130] = (endTime & 0xff00) >> 8
|
|
||||||
paramsArray[131] = (endTime & 0xff)
|
|
||||||
|
|
||||||
// 有效次数
|
|
||||||
paramsArray[132] = 0xffff / 256
|
|
||||||
paramsArray[133] = 0xffff % 256
|
|
||||||
|
|
||||||
// 是否循环
|
|
||||||
paramsArray[134] = 0
|
|
||||||
// 循环周期
|
|
||||||
paramsArray[135] = 0
|
|
||||||
// 开始小时
|
|
||||||
paramsArray[136] = 0
|
|
||||||
// 开始分钟
|
|
||||||
paramsArray[137] = 0
|
|
||||||
// 结束小时
|
|
||||||
paramsArray[138] = 0
|
|
||||||
// 结束分钟
|
|
||||||
paramsArray[139] = 0
|
|
||||||
// 用户角色
|
|
||||||
paramsArray[140] = 0xff
|
|
||||||
|
|
||||||
// 随机密码
|
|
||||||
const password = this.password == '' ? (Math.floor(Math.random() * 900000) + 100000).toString() : this.password.toString()
|
|
||||||
console.log('随机密码', password)
|
|
||||||
for(let i = 0; i < password.length; i++){
|
|
||||||
paramsArray[141 + i] = password.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
for(let i = 0; i < this.token.length; i++){
|
|
||||||
paramsArray[161 + i] = this.token[i]
|
|
||||||
}
|
|
||||||
// MD5长度
|
|
||||||
paramsArray[165] = 16
|
|
||||||
|
|
||||||
const originAuthCodeLen = this.keyId.length + this.uid.length + 4 + 16
|
|
||||||
let authCodeBinaryData = new Uint8Array(originAuthCodeLen)
|
|
||||||
|
|
||||||
for(let i=0; i < this.uid.length; i++){
|
|
||||||
authCodeBinaryData[i] = this.uid.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
for(let i=0; i < this.keyId.length; i++){
|
|
||||||
authCodeBinaryData[this.uid.length + i] = this.keyId.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
const number = this.keyId.length + this.uid.length
|
|
||||||
|
|
||||||
if(this.token[0] === 0 && this.token[1] === 0 && this.token[2] === 0 && this.token[3] === 0){
|
|
||||||
authCodeBinaryData[number + 0] = (nowTime & 0xff000000) >> 24
|
|
||||||
authCodeBinaryData[number + 1] = (nowTime & 0xff0000) >> 16
|
|
||||||
authCodeBinaryData[number + 2] = (nowTime & 0xff00) >> 8
|
|
||||||
authCodeBinaryData[number + 3] = (nowTime & 0xff)
|
|
||||||
} else {
|
|
||||||
authCodeBinaryData[number + 0] = this.token[0]
|
|
||||||
authCodeBinaryData[number + 1] = this.token[1]
|
|
||||||
authCodeBinaryData[number + 2] = this.token[2]
|
|
||||||
authCodeBinaryData[number + 3] = this.token[3]
|
|
||||||
}
|
|
||||||
|
|
||||||
for(let i=0; i < 16; i++){
|
|
||||||
authCodeBinaryData[number + 4 + i] = this.publicKey[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('md5前的数据', Array.from(authCodeBinaryData))
|
|
||||||
const md5Hex = md5(authCodeBinaryData)
|
|
||||||
const md5Array = new Uint8Array(md5Hex.match(/.{1,2}/g).map(byte => parseInt(byte, 16)))
|
|
||||||
console.log('md5后的数据', Array.from(md5Array))
|
|
||||||
|
|
||||||
for(let i = 0; i < md5Array.length; i++) {
|
|
||||||
paramsArray[166 + i] = md5Array[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('未加密的数据', Array.from(paramsArray))
|
|
||||||
const encryptArray = sm4.encrypt(paramsArray, this.commKey, { mode: 'ecb', output: 'array' })
|
|
||||||
console.log('加密后的数据', Array.from(encryptArray))
|
|
||||||
|
|
||||||
// 合并头部数据和加密数据
|
|
||||||
let mergeBuffer = new ArrayBuffer(204)
|
|
||||||
let mergeArray = new Uint8Array(mergeBuffer)
|
|
||||||
for(let i = 0; i < 12; i++){
|
|
||||||
mergeArray[i] = headArray[i]
|
|
||||||
}
|
|
||||||
for(let i = 0; i < 192; i++){
|
|
||||||
mergeArray[i + 12] = encryptArray[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('crc前的数据', Array.from(mergeArray))
|
|
||||||
let resultBuffer = new ArrayBuffer(206)
|
|
||||||
let resultArray = new Uint8Array(resultBuffer)
|
|
||||||
for(let i = 0; i < 204; i++){
|
|
||||||
resultArray[i] = mergeArray[i]
|
|
||||||
}
|
|
||||||
resultArray[204] = crc.crc16kermit(mergeBuffer) / 256
|
|
||||||
resultArray[205] = crc.crc16kermit(mergeBuffer) % 256
|
|
||||||
this.writeBLECharacteristicValue(resultBuffer)
|
|
||||||
},
|
|
||||||
reconnect() {
|
|
||||||
return new Promise(resolve => setTimeout(resolve, 2000))
|
|
||||||
},
|
|
||||||
// 开门
|
|
||||||
async openDoor() {
|
|
||||||
const that = this
|
|
||||||
|
|
||||||
that.connect(that.config)
|
|
||||||
// 重连
|
|
||||||
const result = await that.reconnect()
|
|
||||||
|
|
||||||
// 头部数据
|
|
||||||
let headArray = new Uint8Array(12)
|
|
||||||
|
|
||||||
// 固定包头
|
|
||||||
headArray[0] = 0xEF
|
|
||||||
headArray[1] = 0x01
|
|
||||||
headArray[2] = 0xEE
|
|
||||||
headArray[3] = 0x02
|
|
||||||
|
|
||||||
// 包类型 发送
|
|
||||||
headArray[4] = 0x01
|
|
||||||
|
|
||||||
// 包序号
|
|
||||||
headArray[5] = this.number / 256
|
|
||||||
headArray[6] = this.number % 256
|
|
||||||
this.number++
|
|
||||||
|
|
||||||
// 包标识
|
|
||||||
headArray[7] = 0x23
|
|
||||||
|
|
||||||
// 数据长度
|
|
||||||
headArray[8] = 112 / 256
|
|
||||||
headArray[9] = 112 % 256
|
|
||||||
headArray[10] = 104 / 256
|
|
||||||
headArray[11] = 104 % 256
|
|
||||||
|
|
||||||
// 入参
|
|
||||||
let paramsArray = new Uint8Array(104)
|
|
||||||
|
|
||||||
// 命令
|
|
||||||
paramsArray[0] = 0x3005 / 256
|
|
||||||
paramsArray[1] = 0x3005 % 256
|
|
||||||
|
|
||||||
// 锁ID
|
|
||||||
for (let i = 0; i < this.lockId.length; i++) {
|
|
||||||
paramsArray[2 + i] = this.lockId.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用户ID
|
|
||||||
for (let i = 0; i < this.uid.length; i++) {
|
|
||||||
paramsArray[42 + i] = this.uid.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 开锁方式
|
|
||||||
paramsArray[62] = 0
|
|
||||||
|
|
||||||
// 启用日期
|
|
||||||
const nowTime = parseInt(new Date().getTime() / 1000)
|
|
||||||
|
|
||||||
paramsArray[63] = (nowTime & 0xff000000) >> 24
|
|
||||||
paramsArray[64] = (nowTime & 0xff0000) >> 16
|
|
||||||
paramsArray[65] = (nowTime & 0xff00) >> 8
|
|
||||||
paramsArray[66] = (nowTime & 0xff)
|
|
||||||
|
|
||||||
// token
|
|
||||||
for (let i = 0; i < this.token.length; i++) {
|
|
||||||
paramsArray[67 + i] = this.token[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// authCode长度
|
|
||||||
paramsArray[71] = 16
|
|
||||||
|
|
||||||
const originAuthCodeLen = this.lockId.length + this.uid.length + 4 + 16
|
|
||||||
let authCodeBinaryData = new Uint8Array(originAuthCodeLen)
|
|
||||||
|
|
||||||
for (let i = 0; i < this.lockId.length; i++) {
|
|
||||||
authCodeBinaryData[i] = this.lockId.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < this.uid.length; i++) {
|
|
||||||
authCodeBinaryData[this.lockId.length + i] = this.uid.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
const number = this.lockId.length + this.uid.length
|
|
||||||
|
|
||||||
authCodeBinaryData[number + 0] = this.token[0]
|
|
||||||
authCodeBinaryData[number + 1] = this.token[1]
|
|
||||||
authCodeBinaryData[number + 2] = this.token[2]
|
|
||||||
authCodeBinaryData[number + 3] = this.token[3]
|
|
||||||
|
|
||||||
for (let i = 0; i < 16; i++) {
|
|
||||||
authCodeBinaryData[number + 4 + i] = this.signKey[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('lockId', this.lockId, 'uid', this.uid, 'token', Array.from(this.token),'signKey',
|
|
||||||
Array.from(this.signKey))
|
|
||||||
console.log('md5前的数据', Array.from(authCodeBinaryData))
|
|
||||||
const md5Hex = md5(authCodeBinaryData)
|
|
||||||
const md5Array = new Uint8Array(md5Hex.match(/.{1,2}/g).map(byte => parseInt(byte, 16)))
|
|
||||||
console.log('md5后的数据', Array.from(md5Array))
|
|
||||||
|
|
||||||
for (let i = 0; i < md5Array.length; i++) {
|
|
||||||
paramsArray[72 + i] = md5Array[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
const onlineToken = '0'
|
|
||||||
for (let i = 0; i < onlineToken.length; i++) {
|
|
||||||
paramsArray[88 + i] = onlineToken.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('未加密的数据', Array.from(paramsArray))
|
|
||||||
const encryptArray = sm4.encrypt(paramsArray, this.commKey, { mode: 'ecb', output: 'array' })
|
|
||||||
console.log('加密后的数据', Array.from(encryptArray))
|
|
||||||
|
|
||||||
// 合并头部数据和加密数据
|
|
||||||
let mergeBuffer = new ArrayBuffer(124)
|
|
||||||
let mergeArray = new Uint8Array(mergeBuffer)
|
|
||||||
for (let i = 0; i < 12; i++) {
|
|
||||||
mergeArray[i] = headArray[i]
|
|
||||||
}
|
|
||||||
for (let i = 0; i < 112; i++) {
|
|
||||||
mergeArray[i + 12] = encryptArray[i]
|
|
||||||
}
|
|
||||||
console.log('crc前的数据', Array.from(mergeArray))
|
|
||||||
|
|
||||||
let resultBuffer = new ArrayBuffer(126)
|
|
||||||
let resultArray = new Uint8Array(resultBuffer)
|
|
||||||
for (let i = 0; i < 124; i++) {
|
|
||||||
resultArray[i] = mergeArray[i]
|
|
||||||
}
|
|
||||||
resultArray[124] = crc.crc16kermit(mergeBuffer) / 256
|
|
||||||
resultArray[125] = crc.crc16kermit(mergeBuffer) % 256
|
|
||||||
this.writeBLECharacteristicValue(resultBuffer)
|
|
||||||
},
|
|
||||||
// 获取锁状态
|
|
||||||
getLockStatus() {
|
|
||||||
// 头部数据
|
|
||||||
let binaryData = new Uint8Array(12)
|
|
||||||
|
|
||||||
// 固定包头
|
|
||||||
binaryData[0] = 0xEF
|
|
||||||
binaryData[1] = 0x01
|
|
||||||
binaryData[2] = 0xEE
|
|
||||||
binaryData[3] = 0x02
|
|
||||||
|
|
||||||
// 包类型 发送
|
|
||||||
binaryData[4] = 0x01
|
|
||||||
|
|
||||||
// 包序号
|
|
||||||
binaryData[5] = this.number / 256
|
|
||||||
binaryData[6] = this.number % 256
|
|
||||||
this.number++
|
|
||||||
|
|
||||||
// 包标识
|
|
||||||
binaryData[7] = 0x23
|
|
||||||
|
|
||||||
// 数据长度
|
|
||||||
binaryData[8] = 80 / 256
|
|
||||||
binaryData[9] = 80 % 256
|
|
||||||
binaryData[10] = 70 / 256
|
|
||||||
binaryData[11] = 70 % 256
|
|
||||||
|
|
||||||
console.log('请求头', Array.from(binaryData))
|
|
||||||
|
|
||||||
// 入参
|
|
||||||
let paramsBuffer = new ArrayBuffer(70)
|
|
||||||
let paramsBinaryData = new Uint8Array(paramsBuffer)
|
|
||||||
|
|
||||||
// 命令
|
|
||||||
paramsBinaryData[0] = 0x3040 / 256
|
|
||||||
paramsBinaryData[1] = 0x3040 % 256
|
|
||||||
|
|
||||||
// 设备ID
|
|
||||||
for(let i=0; i < this.lockId.length; i++){
|
|
||||||
paramsBinaryData[2 + i] = this.lockId.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// userId
|
|
||||||
const authUserId = '294'
|
|
||||||
for(let i=0; i < authUserId.length; i++){
|
|
||||||
paramsBinaryData[42 + i] = authUserId.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
const nowTime = parseInt(new Date().getTime() / 1000)
|
|
||||||
|
|
||||||
paramsBinaryData[62] = (nowTime & 0xff000000) >> 24
|
|
||||||
paramsBinaryData[62 + 1] = (nowTime & 0xff0000) >> 16
|
|
||||||
paramsBinaryData[62 + 2] = (nowTime & 0xff00) >> 8
|
|
||||||
paramsBinaryData[62 + 3] = (nowTime & 0xff)
|
|
||||||
|
|
||||||
paramsBinaryData[66] = (nowTime & 0xff000000) >> 24
|
|
||||||
paramsBinaryData[66 + 1] = (nowTime & 0xff0000) >> 16
|
|
||||||
paramsBinaryData[66 + 2] = (nowTime & 0xff00) >> 8
|
|
||||||
paramsBinaryData[66 + 3] = (nowTime & 0xff)
|
|
||||||
|
|
||||||
console.log('ecb加密前入参', Array.from(paramsBinaryData))
|
|
||||||
console.log('密钥', Array.from(this.commKey))
|
|
||||||
const encrypted = sm4.encrypt(paramsBinaryData, this.commKey, { mode: 'ecb', output: 'array' })
|
|
||||||
console.log('ecb加密后的数据', Array.from(encrypted))
|
|
||||||
|
|
||||||
let newBuffer = new ArrayBuffer(92)
|
|
||||||
let newBinaryData = new Uint8Array(newBuffer)
|
|
||||||
for(let i = 0; i < 12; i++){
|
|
||||||
newBinaryData[i] = binaryData[i]
|
|
||||||
}
|
|
||||||
for(let i = 0; i < 80; i++){
|
|
||||||
newBinaryData[i + 12] = encrypted[i]
|
|
||||||
}
|
|
||||||
console.log('crc前的数据', Array.from(newBinaryData))
|
|
||||||
let resultBuffer = new ArrayBuffer(94)
|
|
||||||
let resultBinaryData = new Uint8Array(resultBuffer)
|
|
||||||
for(let i = 0; i < 92; i++){
|
|
||||||
resultBinaryData[i] = newBinaryData[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
resultBinaryData[92] = crc.crc16kermit(newBuffer) / 256
|
|
||||||
resultBinaryData[93] = crc.crc16kermit(newBuffer) % 256
|
|
||||||
this.writeBLECharacteristicValue(resultBuffer)
|
|
||||||
},
|
|
||||||
// 十六进制字符串转Uint8Array
|
|
||||||
hexToUint8Array(hex) {
|
|
||||||
if (hex.length % 2 !== 0) {
|
|
||||||
throw new Error('Invalid hex string')
|
|
||||||
}
|
|
||||||
const array = new Uint8Array(hex.length / 2)
|
|
||||||
for (let i = 0; i < hex.length; i += 2) {
|
|
||||||
array[i / 2] = parseInt(hex.substr(i, 2), 16)
|
|
||||||
}
|
|
||||||
return array
|
|
||||||
},
|
|
||||||
// 获取私钥
|
|
||||||
getCommKey() {
|
|
||||||
const keyId = '0'
|
|
||||||
const authUserId = '294'
|
|
||||||
const nowTime = parseInt(new Date().getTime() / 1000)
|
|
||||||
|
|
||||||
const originAuthCodeLen = keyId.length + authUserId.length + 4 + 16
|
|
||||||
|
|
||||||
let authCodeBuffer = new ArrayBuffer(originAuthCodeLen)
|
|
||||||
let authCodeBinaryData = new Uint8Array(authCodeBuffer)
|
|
||||||
|
|
||||||
for(let i=0; i < authUserId.length; i++){
|
|
||||||
authCodeBinaryData[i] = authUserId.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
for(let i=0; i < keyId.length; i++){
|
|
||||||
authCodeBinaryData[authUserId.length + i] = keyId.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
const number = keyId.length + authUserId.length
|
|
||||||
authCodeBinaryData[number + 0] = (nowTime & 0xff000000) >> 24
|
|
||||||
authCodeBinaryData[number + 1] = (nowTime & 0xff0000) >> 16
|
|
||||||
authCodeBinaryData[number + 2] = (nowTime & 0xff00) >> 8
|
|
||||||
authCodeBinaryData[number + 3] = (nowTime & 0xff)
|
|
||||||
|
|
||||||
for(let i=0; i < 16; i++){
|
|
||||||
authCodeBinaryData[number + 4 + i] = this.publicKey[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('钥ID', keyId, '用户ID', authUserId, '时间戳', nowTime,'公钥', Array.from(this.publicKey))
|
|
||||||
console.log('md5前的数据', Array.from(authCodeBinaryData, byte =>
|
|
||||||
byte.toString(10)).join(','))
|
|
||||||
const md5Hex = md5(authCodeBinaryData)
|
|
||||||
const codeMd5 = new Uint8Array(md5Hex.match(/.{1,2}/g).map(byte => parseInt(byte, 16)))
|
|
||||||
console.log('md5后的数据', codeMd5, codeMd5.length)
|
|
||||||
|
|
||||||
const bufferLength = codeMd5.length + 12 + 107
|
|
||||||
|
|
||||||
let buffer = new ArrayBuffer(bufferLength)
|
|
||||||
let binaryData = new Uint8Array(buffer)
|
|
||||||
|
|
||||||
// 固定包头
|
|
||||||
binaryData[0] = 0xEF
|
|
||||||
binaryData[1] = 0x01
|
|
||||||
binaryData[2] = 0xEE
|
|
||||||
binaryData[3] = 0x02
|
|
||||||
|
|
||||||
// 包类型 发送
|
|
||||||
binaryData[4] = 0x01
|
|
||||||
|
|
||||||
// 包序号
|
|
||||||
binaryData[5] = this.number / 256
|
|
||||||
binaryData[6] = this.number % 256
|
|
||||||
this.number++
|
|
||||||
|
|
||||||
// 包标识
|
|
||||||
binaryData[7] = 0x22
|
|
||||||
|
|
||||||
// 数据长度
|
|
||||||
binaryData[10] = (codeMd5.length + 107) / 256
|
|
||||||
binaryData[11] = (codeMd5.length + 107) % 256
|
|
||||||
|
|
||||||
// 命令
|
|
||||||
binaryData[12] = 0x3091 / 256
|
|
||||||
binaryData[13] = 0x3091 % 256
|
|
||||||
|
|
||||||
for(let i=0; i < this.lockId.length; i++){
|
|
||||||
binaryData[14 + i] = this.lockId.charCodeAt(i)
|
|
||||||
}
|
|
||||||
let flagNumber = 14 + 40
|
|
||||||
for (let i = 0; i < keyId.length; i++) {
|
|
||||||
binaryData[flagNumber + i] = keyId.charCodeAt(i)
|
|
||||||
}
|
|
||||||
flagNumber += 40
|
|
||||||
for (let i = 0; i < authUserId.length; i++) {
|
|
||||||
binaryData[flagNumber + i] = authUserId.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
flagNumber += 20
|
|
||||||
binaryData[flagNumber + 0] = (nowTime & 0xff000000) >> 24
|
|
||||||
binaryData[flagNumber + 1] = (nowTime & 0xff0000) >> 16
|
|
||||||
binaryData[flagNumber + 2] = (nowTime & 0xff00) >> 8
|
|
||||||
binaryData[flagNumber + 3] = (nowTime & 0xff)
|
|
||||||
|
|
||||||
flagNumber += 4
|
|
||||||
binaryData[flagNumber] = codeMd5.length
|
|
||||||
flagNumber += 1
|
|
||||||
for (let i = 0; i < codeMd5.length; i++) {
|
|
||||||
binaryData[flagNumber + i] = codeMd5[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
binaryData[8] = Math.ceil((bufferLength - 12)/16) * 16 / 256
|
|
||||||
binaryData[9] = Math.ceil((bufferLength - 12)/16) * 16 % 256
|
|
||||||
|
|
||||||
let cebBuffer = new ArrayBuffer(bufferLength - 12)
|
|
||||||
let cebBinaryData = new Uint8Array(cebBuffer)
|
|
||||||
|
|
||||||
for(let i = 0; i < bufferLength - 12; i++){
|
|
||||||
cebBinaryData[i] = binaryData[i + 12]
|
|
||||||
}
|
|
||||||
|
|
||||||
const key = new Uint8Array(16)
|
|
||||||
for (let i = 0; i < this.lockId.length; i++) {
|
|
||||||
key[i] = this.lockId.charCodeAt(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('未加密的数据', Array.from(cebBinaryData))
|
|
||||||
const encrypted = sm4.encrypt(cebBinaryData, key, { mode: 'ecb' })
|
|
||||||
const newBinaryData = this.hexToUint8Array(encrypted)
|
|
||||||
console.log('ecb加密后的数据', Array.from(newBinaryData))
|
|
||||||
|
|
||||||
const encrypteBuffer = new ArrayBuffer(12 + newBinaryData.length)
|
|
||||||
const encrypteBinaryData = new Uint8Array(encrypteBuffer)
|
|
||||||
for(let i = 0; i< 12; i++){
|
|
||||||
encrypteBinaryData[i] = binaryData[i]
|
|
||||||
}
|
|
||||||
for(let i = 12; i < encrypteBinaryData.length; i++){
|
|
||||||
encrypteBinaryData[i] = newBinaryData[i - 12]
|
|
||||||
}
|
|
||||||
console.log('crc前的数据', Array.from(encrypteBinaryData))
|
|
||||||
|
|
||||||
const resultBuffer = new ArrayBuffer(encrypteBinaryData.length + 2)
|
|
||||||
const resultBinaryData = new Uint8Array(resultBuffer)
|
|
||||||
for(let i = 0; i< encrypteBinaryData.length; i++){
|
|
||||||
resultBinaryData[i] = encrypteBinaryData[i]
|
|
||||||
}
|
|
||||||
resultBinaryData[encrypteBinaryData.length] = crc.crc16kermit(encrypteBuffer) / 256
|
|
||||||
resultBinaryData[1 + encrypteBinaryData.length] = crc.crc16kermit(encrypteBuffer) % 256
|
|
||||||
|
|
||||||
this.writeBLECharacteristicValue(resultBuffer)
|
|
||||||
},
|
|
||||||
// 获取公钥
|
|
||||||
getPublicKey() {
|
|
||||||
let buffer = new ArrayBuffer(54)
|
|
||||||
let binaryData = new Uint8Array(buffer)
|
|
||||||
|
|
||||||
// 固定包头
|
|
||||||
binaryData[0] = 0xEF
|
|
||||||
binaryData[1] = 0x01
|
|
||||||
binaryData[2] = 0xEE
|
|
||||||
binaryData[3] = 0x02
|
|
||||||
|
|
||||||
// 包类型 发送
|
|
||||||
binaryData[4] = 0x01
|
|
||||||
|
|
||||||
// 包序号
|
|
||||||
binaryData[5] = this.number / 256
|
|
||||||
binaryData[6] = this.number % 256
|
|
||||||
this.number++
|
|
||||||
|
|
||||||
// 包标识
|
|
||||||
binaryData[7] = 0x20
|
|
||||||
|
|
||||||
// 数据长度
|
|
||||||
binaryData[8] = 42 / 256
|
|
||||||
binaryData[9] = 42 % 256
|
|
||||||
binaryData[10] = 42 / 256
|
|
||||||
binaryData[11] = 42 % 256
|
|
||||||
|
|
||||||
// 命令
|
|
||||||
binaryData[12] = 0x3090 / 256
|
|
||||||
binaryData[13] = 0x3090 % 256
|
|
||||||
|
|
||||||
// // 设备ID
|
|
||||||
for(let i=0; i < this.lockId.length; i++){
|
|
||||||
binaryData[14 + i] = this.lockId.charCodeAt(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// crc
|
|
||||||
|
|
||||||
let newBuffer = new ArrayBuffer(56)
|
|
||||||
let newBinaryData = new Uint8Array(newBuffer)
|
|
||||||
for(let i = 0; i < 54; i++){
|
|
||||||
newBinaryData[i] = binaryData[i]
|
|
||||||
}
|
|
||||||
newBinaryData[54] = crc.crc16kermit(buffer) / 256
|
|
||||||
newBinaryData[55] = crc.crc16kermit(buffer) % 256
|
|
||||||
this.writeBLECharacteristicValue(newBuffer)
|
|
||||||
},
|
|
||||||
// 写入输入
|
|
||||||
writeBLECharacteristicValue(data) {
|
|
||||||
const that = this
|
|
||||||
console.log('写入设备的设备 ID',that.deviceId)
|
|
||||||
console.log('写入设备的serviceId',that.serviceId)
|
|
||||||
console.log('写入设备的characteristicId',that.characteristicId2)
|
|
||||||
console.log('写入设备的lockID',that.lockId)
|
|
||||||
|
|
||||||
let Uint8ArrayData = new Uint8Array(data)
|
|
||||||
|
|
||||||
console.log('未加工的数据', Array.from(Uint8ArrayData))
|
|
||||||
|
|
||||||
for(let i = 0; i < Math.ceil(data.byteLength / 20); i++){
|
|
||||||
let length = i === (Math.ceil(data.byteLength / 20)-1)?data.byteLength%20:20
|
|
||||||
let buffer = new ArrayBuffer(length)
|
|
||||||
let binaryData = new Uint8Array(buffer)
|
|
||||||
for(let j = 0; j < 20; j++){
|
|
||||||
if(i * 20 + j < data.byteLength){
|
|
||||||
binaryData[j] = Uint8ArrayData[i * 20 + j]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uni.writeBLECharacteristicValue({
|
|
||||||
deviceId: that.deviceId,
|
|
||||||
serviceId: that.serviceId,
|
|
||||||
characteristicId: that.characteristicId2,
|
|
||||||
value: buffer,
|
|
||||||
success() {
|
|
||||||
const hexString = Array.from(binaryData, byte =>
|
|
||||||
byte.toString(10)).join(',')
|
|
||||||
console.log('写入的数据', hexString)
|
|
||||||
console.log('写入成功')
|
|
||||||
},
|
|
||||||
fail(res) {
|
|
||||||
console.log('写入失败')
|
|
||||||
console.log(res)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 解析特征值返回数据
|
|
||||||
parsingdata(binaryData) {
|
|
||||||
const that = this
|
|
||||||
// 明文 0x20 SM4事先约定密钥 0x22
|
|
||||||
if(binaryData[7] === 0x20) {
|
|
||||||
if(binaryData[12] === 48 && binaryData[13] === 144){
|
|
||||||
const publicKey = binaryData.slice(15, 31)
|
|
||||||
console.log('公钥', Array.from(publicKey))
|
|
||||||
that.publicKey = publicKey
|
|
||||||
}
|
|
||||||
} else if(binaryData[7] === 0x22) {
|
|
||||||
const cebBinaryData = binaryData.slice(12, binaryData.length - 2)
|
|
||||||
console.log('sm4返回参数', Array.from(cebBinaryData))
|
|
||||||
const key = new Uint8Array(16)
|
|
||||||
for (let i = 0; i < that.lockId.length; i++) {
|
|
||||||
key[i] = that.lockId.charCodeAt(i)
|
|
||||||
}
|
|
||||||
const decrypted = sm4.decrypt(cebBinaryData, key, { mode: 'ecb', output: 'array' })
|
|
||||||
console.log('ecb解密后的数据', decrypted)
|
|
||||||
if(decrypted[0] === 48 && decrypted[1] === 145) {
|
|
||||||
that.commKey = decrypted.slice(3, 19)
|
|
||||||
that.signKey = decrypted.slice(19, 35)
|
|
||||||
console.log('commKey', Array.from(that.commKey))
|
|
||||||
console.log('signKey', Array.from(that.signKey))
|
|
||||||
}
|
|
||||||
} else if(binaryData[7] === 0x23) {
|
|
||||||
const cebBinaryData = binaryData.slice(12, binaryData.length - 2)
|
|
||||||
console.log('sm4返回参数', Array.from(cebBinaryData))
|
|
||||||
const decrypted = sm4.decrypt(cebBinaryData, that.commKey, { mode: 'ecb', output: 'array' })
|
|
||||||
console.log('ecb解密后的数据', decrypted)
|
|
||||||
if(decrypted[0] === 48 && decrypted[1] === 64) {
|
|
||||||
that.lockStatus = decrypted
|
|
||||||
console.log('锁状态', that.lockStatus)
|
|
||||||
} else if(decrypted[0] === 48 && decrypted[1] === 1) {
|
|
||||||
that.token = decrypted.slice(42,46)
|
|
||||||
console.log('token', Array.from(that.token))
|
|
||||||
if(decrypted[46] === 6) {
|
|
||||||
that.addUser()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(decrypted[0] === 48 && decrypted[1] === 5) {
|
|
||||||
that.token = decrypted.slice(2,6)
|
|
||||||
console.log('token', Array.from(that.token))
|
|
||||||
if(decrypted[6] === 6) {
|
|
||||||
that.openDoor()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 监听特征值变化
|
|
||||||
notifyBLECharacteristicValueChange() {
|
|
||||||
const that = this
|
|
||||||
let completeData
|
|
||||||
let length
|
|
||||||
uni.notifyBLECharacteristicValueChange({
|
|
||||||
state: true,
|
|
||||||
deviceId: that.deviceId,
|
|
||||||
serviceId: that.serviceId,
|
|
||||||
characteristicId: that.characteristicId1,
|
|
||||||
type: 'notification',
|
|
||||||
success(res) {
|
|
||||||
console.log(res)
|
|
||||||
if(that.notify) return
|
|
||||||
uni.onBLECharacteristicValueChange(function (res) {
|
|
||||||
that.notify = true
|
|
||||||
let binaryData = new Uint8Array(res.value)
|
|
||||||
console.log('设备返回的数据', Array.from(binaryData), Array.from(binaryData, byte =>
|
|
||||||
byte.toString(16)).join(','))
|
|
||||||
if(binaryData[0] === 239 && binaryData[1] === 1 && binaryData[2] === 238 && binaryData[3] === 2) {
|
|
||||||
length = binaryData[8] * 256 + binaryData[9]
|
|
||||||
if(length + 14 > binaryData.length) {
|
|
||||||
completeData = binaryData
|
|
||||||
} else {
|
|
||||||
that.parsingdata(binaryData)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(completeData.length > 0) {
|
|
||||||
const combinedArray = new Uint8Array(completeData.length + binaryData.length)
|
|
||||||
combinedArray.set(completeData, 0);
|
|
||||||
combinedArray.set(binaryData, completeData.length)
|
|
||||||
completeData = combinedArray
|
|
||||||
if(length + 14 === completeData.length) {
|
|
||||||
that.parsingdata(completeData)
|
|
||||||
completeData = new Uint8Array(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 连接蓝牙设备
|
|
||||||
connect(item) {
|
|
||||||
this.config = item
|
|
||||||
const that = this
|
|
||||||
if(item.pair) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
uni.createBLEConnection({
|
|
||||||
deviceId: item.deviceId,
|
|
||||||
success(res) {
|
|
||||||
console.log('连接成功')
|
|
||||||
console.log(res)
|
|
||||||
uni.getBLEDeviceServices({
|
|
||||||
deviceId: item.deviceId,
|
|
||||||
success(res) {
|
|
||||||
console.log('获取服务成功')
|
|
||||||
console.log(res.services)
|
|
||||||
const uuid = res.services[0].uuid
|
|
||||||
that.lockId = item.name
|
|
||||||
console.log('锁ID', that.lockId)
|
|
||||||
uni.getBLEDeviceCharacteristics({
|
|
||||||
deviceId: item.deviceId,
|
|
||||||
serviceId: uuid,
|
|
||||||
success(res) {
|
|
||||||
console.log('获取特征值成功')
|
|
||||||
console.log(res)
|
|
||||||
that.deviceId = item.deviceId
|
|
||||||
that.serviceId = uuid
|
|
||||||
for (let i = 0; i < res.characteristics.length; i++) {
|
|
||||||
if (res.characteristics[i].uuid.indexOf("FFF1") !== -1) {
|
|
||||||
that.characteristicId1 = res.characteristics[i].uuid
|
|
||||||
}
|
|
||||||
if (res.characteristics[i].uuid.indexOf("FFF2") !== -1) {
|
|
||||||
that.characteristicId2 = res.characteristics[i].uuid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
that.showList = false
|
|
||||||
that.notifyBLECharacteristicValueChange()
|
|
||||||
uni.showToast({
|
|
||||||
title: '数据获取成功',
|
|
||||||
icon: 'none',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
},
|
|
||||||
fail(res) {
|
|
||||||
console.log('获取特征值失败')
|
|
||||||
console.log(res)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
fail(res) {
|
|
||||||
console.log('获取服务失败')
|
|
||||||
console.log(res)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
fail(res) {
|
|
||||||
console.log('连接失败')
|
|
||||||
console.log(res)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 监听蓝牙设备列表变化
|
|
||||||
startGetList() {
|
|
||||||
const that = this
|
|
||||||
this.getting = true
|
|
||||||
console.log('开始监听蓝牙列表更新')
|
|
||||||
uni.startBluetoothDevicesDiscovery({
|
|
||||||
allowDuplicatesKey: false,
|
|
||||||
powerLevel: 'high',
|
|
||||||
success: function (res) {
|
|
||||||
// 更新列表
|
|
||||||
console.log('列表发生变化', res)
|
|
||||||
that.getList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 获取蓝牙设备列表
|
|
||||||
getList() {
|
|
||||||
const that = this
|
|
||||||
uni.getBluetoothDevices({
|
|
||||||
success(res) {
|
|
||||||
console.log('获取设备列表成功')
|
|
||||||
console.log(res)
|
|
||||||
that.list = []
|
|
||||||
for(let i =0; i < res.devices.length; i++){
|
|
||||||
if(res.devices[i]?.advertisServiceUUIDs) {
|
|
||||||
const advertisServiceUUIDs =
|
|
||||||
res.devices[i]?.advertisServiceUUIDs[0]
|
|
||||||
if(advertisServiceUUIDs &&
|
|
||||||
advertisServiceUUIDs.slice(2,8)==='758824'){
|
|
||||||
res.devices[i].pair =
|
|
||||||
advertisServiceUUIDs.slice(30,32) === '01'
|
|
||||||
res.devices[i].sleep =
|
|
||||||
advertisServiceUUIDs.slice(32,34) === '00'
|
|
||||||
that.list.push(res.devices[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(that.list)
|
|
||||||
if(!that.getting) {
|
|
||||||
that.startGetList()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fail(res) {
|
|
||||||
console.log('获取设备列表失败')
|
|
||||||
console.log(res)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.device {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
margin-top: 200rpx;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
Loading…
x
Reference in New Issue
Block a user