1602 lines
70 KiB
JavaScript
Raw Normal View History

import {sm4} from 'sm-crypto'
2024-12-19 16:01:45 +08:00
import {
arrayToTimestamp,
convertWeekdaysToNumber,
createPackageEnd,
md5Encrypt, parseNetworkJsonFromDecrypted, parseWifiList,
removeTrailingZeros,
timestampToArray,
uint8ArrayToString
2024-12-19 16:01:45 +08:00
} from './format'
import {configs} from './env'
import {cmdIds, Result, subCmdIds, supportFunctionsFeatureBit} from './constant'
2024-12-19 16:01:45 +08:00
import {
closeBLEConnection,
searchAndConnectDevice,
writeBLECharacteristicValue
2024-12-20 09:01:21 +08:00
} from './uni/basic'
2024-12-19 16:01:45 +08:00
import {
addCustomPasswordRequest, addFaceRequest,
addFingerprintRequest,
2025-03-08 10:50:25 +08:00
addIcCardRequest, addPalmVeinRequest, addRemoteRequest,
changeAdminKeyboardPwdRequest, clearAllFace,
clearAllFingerprint,
2025-03-08 10:38:30 +08:00
clearAllIcCard, clearAllPalmVein,
deleteFaceRequest,
deleteFingerprintRequest,
deleteIcCardRequest,
2025-03-08 10:38:30 +08:00
deleteLockRequest, deletePalmVeinRequest,
deletePasswordRequest,
getLastRecordTimeRequest,
getLockNetTokenRequest,
getStarCloudToken,
getUserNoListRequest, updateDeviceNetworkInfo,
updateElectricQuantityRequest,
updateFaceRequest,
updateFingerprintRequest,
updateIcCardRequest, updateLockSettingRequest,
2025-03-08 10:38:30 +08:00
updateLockUserNoRequest, updatePalmVeinRequest,
2025-03-08 10:50:25 +08:00
updatePasswordRequest, updateRemoteRequest,
uploadRecordRequest
2024-12-19 16:01:45 +08:00
} from './api'
import {
buildNumber,
2025-03-08 10:50:25 +08:00
emitRegisterCardConfirmEvent,
emitRegisterFaceConfirmEvent,
emitRegisterFaceProcessEvent,
emitRegisterFingerprintConfirmEvent,
emitRegisterFingerprintProcessEvent,
emitRegisterPalmVeinConfirmEvent,
emitRegisterRemoteConfirmEvent,
getStorage,
setStorage,
version
} from './export'
2024-12-19 17:34:15 +08:00
import log from './log'
2025-06-11 17:29:21 +08:00
import {emitSearchWiFiResultEventUni} from "./uni/storage.js";
2024-12-19 16:01:45 +08:00
/**
* 同步开门记录
* @param params
2024-12-20 17:36:14 +08:00
* @param {Number} [params.uid] 用户ID
* @param {Boolean} [params.disconnect] 操作后是否断开连接, 默认断开
2024-12-19 16:01:45 +08:00
* @returns {Promise<Result>}
*/
export async function syncOpenRecord(params) {
// 设置执行账号
const result = await this.login(params.uid)
if (result.code !== Result.Success.code) {
return result
2024-12-19 16:01:45 +08:00
}
// 确认设备连接正常
if (!params.connected) {
const searchResult = await searchAndConnectDevice(this.lockInfo.bluetooth.bluetoothDeviceName)
if (searchResult.code !== Result.Success.code) {
return searchResult
}
this.updateLockInfo(searchResult.data)
}
2024-12-19 16:01:45 +08:00
// 检查是否已添加为用户
const checkResult = await this.checkLockUser()
if (checkResult.code !== Result.Success.code) {
return checkResult
}
2024-12-19 16:01:45 +08:00
const uid = this.lockInfo.uid.toString()
const keyId = this.lockInfo.keyId.toString()
const logsCount = 10
2024-12-19 16:01:45 +08:00
const timeResult = await getLastRecordTimeRequest({
lockId: this.lockInfo.lockId
})
2024-12-19 16:01:45 +08:00
if (timeResult.code !== Result.Success.code) {
return timeResult
}
2024-12-19 16:01:45 +08:00
const operateDate = Math.ceil(timeResult.data.operateDate / 1000)
const currentDate = Math.ceil(timeResult.data.currentDate / 1000)
2024-12-19 16:01:45 +08:00
const length = 2 + 1 + 1 + 40 + 20 + 2 + 4 + 4 + 1 + 16
const headArray = this.createPackageHeader(3, length)
2024-12-19 16:01:45 +08:00
const contentArray = new Uint8Array(length)
contentArray[0] = cmdIds.expandCmd / 256
contentArray[1] = cmdIds.expandCmd % 256
2024-12-19 16:01:45 +08:00
// 子命令
contentArray[2] = subCmdIds.syncOpenRecord
2024-12-19 16:01:45 +08:00
contentArray[3] = length - 3
2024-12-19 16:01:45 +08:00
for (let i = 0; i < keyId.length; i++) {
contentArray[i + 4] = keyId.charCodeAt(i)
}
2024-12-19 16:01:45 +08:00
for (let i = 0; i < uid.length; i++) {
contentArray[i + 44] = uid.charCodeAt(i)
}
2024-12-19 16:01:45 +08:00
contentArray[64] = logsCount / 256
contentArray[65] = logsCount % 256
2024-12-19 16:01:45 +08:00
contentArray.set(timestampToArray(operateDate), 66)
contentArray.set(timestampToArray(currentDate), 70)
2024-12-19 16:01:45 +08:00
contentArray[74] = 16
2024-12-19 16:01:45 +08:00
const md5Array = md5Encrypt(
uid + keyId,
this.lockInfo.token || new Uint8Array([0, 0, 0, 0]),
this.lockInfo.bluetooth.publicKey
)
2024-12-19 16:01:45 +08:00
contentArray.set(md5Array, 75)
2024-12-19 16:01:45 +08:00
const cebArray = sm4.encrypt(contentArray, this.lockInfo.bluetooth.privateKey, {
mode: 'ecb',
output: 'array'
})
const packageArray = createPackageEnd(headArray, cebArray)
2024-12-19 16:01:45 +08:00
const writeResult = await writeBLECharacteristicValue(
this.lockInfo.deviceId,
this.lockInfo.serviceId,
this.lockInfo.writeCharacteristicId,
packageArray
)
2024-12-19 16:01:45 +08:00
if (writeResult.code !== Result.Success.code) {
return writeResult
}
2024-12-19 16:01:45 +08:00
return this.getWriteResult(this.syncOpenRecord, params)
2024-12-19 16:01:45 +08:00
}
/**
* 清理用户
* @returns {Promise<Result>}
*/
export async function cleanLockUser() {
// 确认设备连接正常
const searchResult = await searchAndConnectDevice(this.lockInfo.bluetooth.bluetoothDeviceName)
if (searchResult.code !== Result.Success.code) {
return searchResult
}
this.updateLockInfo(searchResult.data)
// 获取并处理锁信息
let {uid: authUid, keyId, token, bluetooth} = this.lockInfo
let {uid} = this.userInfo
authUid = authUid.toString()
uid = uid.toString()
keyId = keyId.toString()
const name = bluetooth.bluetoothDeviceName
// 获取用户列表
const {code: requestCode, data: requestData} = await getUserNoListRequest({
lockId: this.lockInfo.lockId
})
console.log('获取用户列表请求结果', requestCode, requestData)
if (requestCode !== 0) return Result.Fail
const userNoList = requestData.userNos
// 组装发送数据
const length = 2 + 40 + 20 + 40 + 20 + 2 + userNoList.length + 4 + 1 + 16
const headArray = this.createPackageHeader(3, length)
const contentArray = new Uint8Array(length)
contentArray[0] = cmdIds.cleanUser / 256
contentArray[1] = cmdIds.cleanUser % 256
for (let i = 0; i < name.length; i++) {
contentArray[i + 2] = name.charCodeAt(i)
}
for (let i = 0; i < authUid.length; i++) {
contentArray[i + 42] = authUid.charCodeAt(i)
}
for (let i = 0; i < keyId.length; i++) {
contentArray[i + 62] = keyId.charCodeAt(i)
}
for (let i = 0; i < uid.length; i++) {
contentArray[i + 102] = uid.charCodeAt(i)
}
contentArray[122] = userNoList.length / 256
contentArray[123] = userNoList.length % 256
for (let i = 0; i < userNoList.length; i++) {
contentArray[i + 124] = userNoList[i]
}
contentArray.set(token || new Uint8Array([0, 0, 0, 0]), 124 + userNoList.length)
contentArray[128 + userNoList.length] = 16
const md5Array = md5Encrypt(
authUid + keyId,
token || new Uint8Array([0, 0, 0, 0]),
bluetooth.publicKey
)
contentArray.set(md5Array, 129 + userNoList.length)
const cebArray = sm4.encrypt(contentArray, bluetooth.privateKey, {
mode: 'ecb',
output: 'array'
})
const packageArray = createPackageEnd(headArray, cebArray)
const writeResult = await writeBLECharacteristicValue(
this.lockInfo.deviceId,
this.lockInfo.serviceId,
this.lockInfo.writeCharacteristicId,
packageArray
)
if (writeResult.code !== Result.Success.code) {
return writeResult
}
return this.getWriteResult(this.cleanLockUser, {disconnect: false})
2024-12-19 16:01:45 +08:00
}
/**
* 登录星云
2024-12-20 17:36:14 +08:00
* @param {Number} [uid] 用户ID
* @param {Boolean} [force] 是否强制更新
2024-12-20 17:36:14 +08:00
* @returns Result
2024-12-19 16:01:45 +08:00
*/
export async function login(uid, force = false) {
let accounts = getStorage('starCloudAccount')
let userInfos = getStorage('starCloudUser')
if (!accounts) {
accounts = {}
}
if (!userInfos) {
userInfos = {}
}
2024-12-19 16:01:45 +08:00
const id = uid || this.accounts[0].uid
this.accountInfo = accounts[id]
2024-12-19 16:01:45 +08:00
if (this.accountInfo) {
if (this.accountInfo.token && !force) {
this.userInfo = userInfos[id]
2024-12-19 16:01:45 +08:00
setStorage('starCloudToken', this.accountInfo.token)
2024-12-19 16:01:45 +08:00
return Result.Success
}
const {
code,
data: userInfo,
message
} = await getStarCloudToken({
username: this.accountInfo.username,
password: this.accountInfo.password,
clientId: this.clientId,
clientSecret: this.clientSecret
})
if (code === Result.Success.code) {
this.userInfo = userInfo
this.accountInfo = {
username: this.accountInfo.username,
password: this.accountInfo.password,
token: userInfo.access_token,
uid: userInfo.uid
}
setStorage('starCloudToken', userInfo.access_token)
accounts[userInfo.uid] = {
uid: userInfo.uid,
username: this.accountInfo.username,
password: this.accountInfo.password,
token: userInfo.access_token
}
setStorage('starCloudAccount', accounts)
userInfos[userInfo.uid] = userInfo
setStorage('starCloudUser', userInfos)
}
return new Result(code, {}, message)
2024-12-19 16:01:45 +08:00
}
return Result.Fail
2024-12-19 16:01:45 +08:00
}
// 获取公钥
export async function getPublicKey() {
const headArray = this.createPackageHeader(0, 42)
2024-12-19 16:01:45 +08:00
const contentArray = new Uint8Array(42)
2024-12-19 16:01:45 +08:00
contentArray[0] = cmdIds.getPublicKey / 256
contentArray[1] = cmdIds.getPublicKey % 256
2024-12-19 16:01:45 +08:00
const name = this.lockInfo.bluetooth.bluetoothDeviceName
2024-12-19 16:01:45 +08:00
for (let i = 0; i < name.length; i++) {
contentArray[i + 2] = name.charCodeAt(i)
}
2024-12-19 16:01:45 +08:00
const packageArray = createPackageEnd(headArray, contentArray)
2024-12-19 16:01:45 +08:00
const writeResult = await writeBLECharacteristicValue(
this.lockInfo.deviceId,
this.lockInfo.serviceId,
this.lockInfo.writeCharacteristicId,
packageArray
)
2024-12-19 16:01:45 +08:00
if (writeResult.code !== Result.Success.code) {
return writeResult
}
2024-12-19 16:01:45 +08:00
return this.getWriteResult(this.getPublicKey, {disconnect: false})
2024-12-19 16:01:45 +08:00
}
// 获取私钥
export async function getCommKey() {
const length = 2 + 40 + 40 + 20 + 4 + 1 + 16
const headArray = this.createPackageHeader(2, length)
const contentArray = new Uint8Array(length)
2024-12-19 16:01:45 +08:00
contentArray[0] = cmdIds.getCommKey / 256
contentArray[1] = cmdIds.getCommKey % 256
2024-12-19 16:01:45 +08:00
const name = this.lockInfo.bluetooth.bluetoothDeviceName
const keyId = '0'
const authUid = this.accountInfo.uid.toString()
await this.getServerTimestamp()
const nowTime = this.serverTimestamp
2024-12-19 16:01:45 +08:00
for (let i = 0; i < name.length; i++) {
contentArray[i + 2] = name.charCodeAt(i)
}
2024-12-19 16:01:45 +08:00
for (let i = 0; i < keyId.length; i++) {
contentArray[i + 42] = keyId.charCodeAt(i)
}
2024-12-19 16:01:45 +08:00
for (let i = 0; i < authUid.length; i++) {
contentArray[i + 82] = authUid.charCodeAt(i)
}
2024-12-19 16:01:45 +08:00
contentArray.set(timestampToArray(nowTime), 102)
2024-12-19 16:01:45 +08:00
contentArray[106] = 16
2024-12-19 16:01:45 +08:00
const md5Array = md5Encrypt(
authUid + keyId,
contentArray.slice(102, 106),
this.lockInfo.bluetooth.publicKey
)
2024-12-19 16:01:45 +08:00
contentArray.set(md5Array, 107)
2024-12-19 16:01:45 +08:00
const cebArray = sm4.encrypt(contentArray, contentArray.slice(2, 18), {
mode: 'ecb',
output: 'array'
})
2024-12-19 16:01:45 +08:00
const packageArray = createPackageEnd(headArray, cebArray)
2024-12-19 16:01:45 +08:00
const writeResult = await writeBLECharacteristicValue(
this.lockInfo.deviceId,
this.lockInfo.serviceId,
this.lockInfo.writeCharacteristicId,
packageArray
)
2024-12-19 16:01:45 +08:00
if (writeResult.code !== Result.Success.code) {
return writeResult
}
2024-12-19 16:01:45 +08:00
return this.getWriteResult(this.getCommKey, {disconnect: false})
2024-12-19 16:01:45 +08:00
}
// 获取锁状态
export async function getLockStatus() {
const length = 2 + 40 + 20 + 4 + 4
const headArray = this.createPackageHeader(3, length)
const contentArray = new Uint8Array(length)
contentArray[0] = cmdIds.getLockStatus / 256
contentArray[1] = cmdIds.getLockStatus % 256
const name = this.lockInfo.bluetooth.bluetoothDeviceName
const uid = this.accountInfo.uid.toString()
await this.getServerTimestamp()
const nowTime = this.serverTimestamp
const date = new Date()
const localTime = this.serverTimestamp - date.getTimezoneOffset() * 60
for (let i = 0; i < name.length; i++) {
contentArray[i + 2] = name.charCodeAt(i)
}
for (let i = 0; i < uid.length; i++) {
contentArray[i + 42] = uid.charCodeAt(i)
}
contentArray.set(timestampToArray(nowTime), 62)
contentArray.set(timestampToArray(localTime), 66)
const cebArray = sm4.encrypt(contentArray, this.lockInfo.bluetooth.privateKey, {
mode: 'ecb',
output: 'array'
})
const packageArray = createPackageEnd(headArray, cebArray)
const writeResult = await writeBLECharacteristicValue(
this.lockInfo.deviceId,
this.lockInfo.serviceId,
this.lockInfo.writeCharacteristicId,
packageArray
)
if (writeResult.code !== Result.Success.code) {
return writeResult
}
return this.getWriteResult(this.getLockStatus, {disconnect: false})
2024-12-19 16:01:45 +08:00
}
// 获取联网token
export async function getNetToken() {
const {code, data, message} = await getLockNetTokenRequest({
lockId: this.lockInfo.lockId
})
return new Result(code, data, message)
2024-12-19 16:01:45 +08:00
}
// 添加用户
export async function addLockUser(params) {
const {params: data} = params
// 确认设备连接正常
if (!params.connected) {
const searchResult = await searchAndConnectDevice(
this.lockInfo.bluetooth.bluetoothDeviceName,
data.role !== 0xff
)
if (searchResult.code !== Result.Success.code) {
return searchResult
}
this.updateLockInfo(searchResult.data)
}
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 contentArray = new Uint8Array(length)
contentArray[0] = cmdIds.addUser / 256
contentArray[1] = cmdIds.addUser % 256
for (let i = 0; i < name.length; i++) {
contentArray[i + 2] = name.charCodeAt(i)
}
for (let i = 0; i < authUid.length; i++) {
contentArray[i + 42] = authUid.charCodeAt(i)
}
2024-12-19 16:01:45 +08:00
for (let i = 0; i < keyId.length; i++) {
contentArray[i + 62] = keyId.charCodeAt(i)
}
for (let i = 0; i < uid.length; i++) {
contentArray[i + 102] = uid.charCodeAt(i)
}
contentArray[122] = openMode
contentArray[123] = keyType
contentArray.set(timestampToArray(startDate), 124)
contentArray.set(timestampToArray(expireDate), 128)
contentArray[132] = useCountLimit / 256
contentArray[133] = useCountLimit % 256
contentArray[134] = isRound
contentArray[135] = weekRound
contentArray[136] = startHour
contentArray[137] = startMin
contentArray[138] = endHour
contentArray[139] = endMin
contentArray[140] = role
for (let i = 0; i < password.length; i++) {
contentArray[i + 141] = password.charCodeAt(i)
}
contentArray.set(this.lockInfo.token || timestampToArray(startDate), 161)
contentArray[165] = 16
const md5Array = md5Encrypt(
authUid + keyId,
this.lockInfo.token || timestampToArray(startDate),
this.lockInfo.bluetooth.publicKey
2024-12-19 16:01:45 +08:00
)
contentArray.set(md5Array, 166)
const cebArray = sm4.encrypt(contentArray, this.lockInfo.bluetooth.privateKey, {
mode: 'ecb',
output: 'array'
})
const packageArray = createPackageEnd(headArray, cebArray)
const writeResult = await writeBLECharacteristicValue(
this.lockInfo.deviceId,
this.lockInfo.serviceId,
this.lockInfo.writeCharacteristicId,
packageArray
)
if (writeResult.code !== Result.Success.code) {
return writeResult
2024-12-19 16:01:45 +08:00
}
return this.getWriteResult(this.addLockUser, params)
2024-12-19 16:01:45 +08:00
}
// 获取写入结果
export function getWriteResult(request, params) {
return new Promise(resolve => {
const getWriteResultTimer = setTimeout(() => {
resolve(Result.Fail)
}, 20000)
this.characteristicValueCallback = async data => {
// code 6 token过期,重新获取
if (data.code === Result.NotTokenLock.code) {
log.info({
...new Result(
data.code,
{
lockName: this.lockInfo.bluetooth.bluetoothDeviceName,
lockId: this.lockInfo.lockId,
time: new Date().getTime()
},
`token过期${data.message}`
),
name: 'openDoor'
})
resolve(await request.call(this, {...params, connected: true}))
} else if (data.code === Result.NotRegisteredLock.code) {
const checkResult = await this.checkLockUser(true)
if (checkResult.code === Result.Success.code) {
resolve(await request.call(this, {...params, connected: true}))
} else {
clearTimeout(getWriteResultTimer)
resolve(checkResult)
}
} else {
clearTimeout(getWriteResultTimer)
if (params.disconnect !== false) {
await this.disconnectDevice()
}
console.log('写入结果', data, request, params)
log.info({
...new Result(
data.code,
{
lockName: this.lockInfo.bluetooth.bluetoothDeviceName,
lockId: this.lockInfo.lockId,
time: new Date().getTime()
},
`开门结果:${data.message}`
),
name: 'openDoor'
})
resolve(data)
}
2024-12-19 16:01:45 +08:00
}
})
2024-12-19 16:01:45 +08:00
}
// 检查是否已添加为用户
export async function checkLockUser(forceAdd = false) {
if (this.lockInfo.lockUserNo === 0 || forceAdd) {
const timestamp = Math.floor(new Date().getTime() / 1000)
const password = (Math.floor(Math.random() * 900000) + 100000).toString()
console.log('用户未添加,开始添加用户')
const addUserParams = {
name: this.lockInfo.bluetooth.bluetoothDeviceName,
keyId: this.lockInfo.keyId.toString(),
authUid: this.lockInfo.uid.toString(),
uid: this.accountInfo.uid.toString(),
openMode: 1,
keyType: 0,
startDate:
this.lockInfo.startDate === 0 ? timestamp : Math.floor(this.lockInfo.startDate / 1000),
expireDate:
this.lockInfo.endDate === 0 ? 0xffffffff : Math.floor(this.lockInfo.endDate / 1000),
useCountLimit: this.lockInfo.keyType === 3 ? 1 : 0xffff,
isRound: this.lockInfo.keyType === 4 ? 1 : 0,
weekRound: this.lockInfo.keyType === 4 ? convertWeekdaysToNumber(this.lockInfo.weekDays) : 0,
startHour: this.lockInfo.keyType === 4 ? new Date(this.lockInfo.startDate).getHours() : 0,
startMin: this.lockInfo.keyType === 4 ? new Date(this.lockInfo.startDate).getMinutes() : 0,
endHour: this.lockInfo.keyType === 4 ? new Date(this.lockInfo.endDate).getHours() : 0,
endMin: this.lockInfo.keyType === 4 ? new Date(this.lockInfo.endDate).getMinutes() : 0,
role: 0,
password
}
const addUserResult = await this.addLockUser({
params: addUserParams,
disconnect: false
})
console.log('添加用户蓝牙结果', addUserResult)
if (addUserResult.code === Result.Success.code) {
const {code} = await updateLockUserNoRequest({
keyId: this.lockInfo.keyId,
lockUserNo: this.lockInfo.lockUserNo
})
console.log('添加用户请求结果', code)
return Result.Success
}
if (addUserResult.code === Result.NotMoreKeyLock.code) {
console.log('用户达上限,开始清理用户')
const {code: cleanCode} = await this.cleanLockUser()
console.log('清理用户蓝牙结果', cleanCode)
if (cleanCode === Result.Success.code) {
return await this.checkLockUser()
}
return Result.Fail
}
if (addUserResult.code === Result.ReadyHasKeyLock.code) {
return Result.Success
}
return Result.Fail
2024-12-19 16:01:45 +08:00
}
return Result.Success
2024-12-19 16:01:45 +08:00
}
// 更新锁信息
export function updateLockInfo(lockInfo) {
this.lockInfo = {
...this.lockInfo,
...lockInfo
}
const lockList = getStorage('starLockList')
if (lockList[this.accountInfo.uid]) {
const index = lockList[this.accountInfo.uid].findIndex(
item => item.lockId === this.lockInfo.lockId
)
if (index !== -1) {
lockList[this.accountInfo.uid][index] = this.lockInfo
}
setStorage('starLockList', lockList)
2024-12-19 16:01:45 +08:00
}
}
// 特征值变化回调
export function listenCharacteristicValue(res) {
if (res.deviceId === this.lockInfo.deviceId) {
let binaryData = new Uint8Array(res.value)
if (
binaryData[0] === 0xef &&
binaryData[1] === 0x01 &&
binaryData[2] === 0xee &&
binaryData[3] === 0x02
) {
this.length = binaryData[8] * 256 + binaryData[9]
if (this.length + 14 > binaryData.length) {
this.completeArray = binaryData
} else {
this.parsingCharacteristicValue(binaryData).then(() => {
})
}
} else if (this.completeArray) {
const combinedArray = new Uint8Array(this.completeArray.length + binaryData.length)
combinedArray.set(this.completeArray, 0)
combinedArray.set(binaryData, this.completeArray.length)
this.completeArray = combinedArray
if (this.length + 14 === this.completeArray.length) {
this.parsingCharacteristicValue(this.completeArray).then(() => {
})
this.completeArray = null
}
}
2024-12-19 16:01:45 +08:00
}
}
// 解析特征值
export async function parsingCharacteristicValue(binaryData) {
// 0x20 明文 0x22 SM4事先约定密钥 0x23 SM4设备指定密钥
if (binaryData[7] === 0x20) {
if (binaryData[12] * 256 + binaryData[13] === cmdIds.getPublicKey) {
if (binaryData[14] === Result.Success.code) {
this.updateLockInfo({
bluetooth: {
...this.lockInfo.bluetooth,
publicKey: [...binaryData.slice(15, 31)]
}
})
}
this.characteristicValueCallback(new Result(binaryData[14]))
2025-06-11 17:29:21 +08:00
} else if (binaryData[12] * 256 + binaryData[13] === cmdIds.searchWiFi) {
this.characteristicValueCallback(new Result(binaryData[14]))
2024-12-19 16:01:45 +08:00
}
2025-06-11 17:29:21 +08:00
// } else if (binaryData[12] * 256 + binaryData[13] === cmdIds.configureNetworkResult) {
// console.log("收到明文数据configureNetworkResult", Array.from(binaryData))
// this.characteristicValueCallback(new Result(binaryData[14]))
// } else if (binaryData[12] * 256 + binaryData[13] === cmdIds.configureNetwork) {
// console.log("收到明文数据configureNetwork", Array.from(binaryData))
// this.characteristicValueCallback(new Result(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 < this.lockInfo.bluetooth.bluetoothDeviceName.length; i++) {
key[i] = this.lockInfo.bluetooth.bluetoothDeviceName.charCodeAt(i)
2024-12-19 16:01:45 +08:00
}
const decrypted = sm4.decrypt(cebBinaryData, key, {
mode: 'ecb',
output: 'array'
})
2025-06-11 17:29:21 +08:00
console.log('SM4事先约定密钥 ecb解密后的数据', decrypted)
if (decrypted[0] * 256 + decrypted[1] === cmdIds.getCommKey) {
2024-12-19 16:01:45 +08:00
if (decrypted[2] === Result.Success.code) {
this.updateLockInfo({
bluetooth: {
...this.lockInfo.bluetooth,
privateKey: decrypted.slice(3, 19),
signKey: decrypted.slice(19, 35)
},
pwdTimestamp: arrayToTimestamp(decrypted.slice(35, 39)) * 1000
})
console.log('privateKey', Array.from(this.lockInfo.bluetooth.privateKey))
console.log('signKey', Array.from(this.lockInfo.bluetooth.signKey))
2024-12-19 16:01:45 +08:00
}
this.characteristicValueCallback(new Result(decrypted[2]))
2025-06-11 17:29:21 +08:00
} else if (decrypted[0] * 256 + decrypted[1] === cmdIds.configureNetworkResult) {
console.log("SM4事先约定密钥 ecb解密后的数据configureNetworkResult", Array.from(binaryData))
this.characteristicValueCallback(new Result(binaryData[14]))
}
} else {
const cebBinaryData = binaryData.slice(12, binaryData.length - 2)
const decrypted = sm4.decrypt(cebBinaryData, this.lockInfo.bluetooth.privateKey, {
mode: 'ecb',
output: 'array',
padding: 'none'
})
2025-06-11 17:29:21 +08:00
console.log('SM4设备指定密钥 ecb解密后的数据', decrypted)
const cmdId = decrypted[0] * 256 + decrypted[1]
switch (cmdId) {
case cmdIds.getLockStatus:
if (decrypted[2] === Result.Success.code) {
const lockConfig = {
vendor: uint8ArrayToString(decrypted.slice(3, 23)),
product: decrypted[23],
model: uint8ArrayToString(decrypted.slice(24, 44)),
fwVersion: uint8ArrayToString(decrypted.slice(44, 64)),
hwVersion: uint8ArrayToString(decrypted.slice(64, 84)),
serialNum0: uint8ArrayToString(decrypted.slice(84, 100)),
serialNum1: uint8ArrayToString(decrypted.slice(100, 116)),
btDeviceName: uint8ArrayToString(decrypted.slice(116, 132)),
electricQuantity: decrypted[132],
electricQuantityStandby: decrypted[133],
restoreCount: decrypted[134] * 256 + decrypted[135],
restoreDate: arrayToTimestamp(decrypted.slice(136, 140)),
icPartNo: uint8ArrayToString(decrypted.slice(140, 150)),
indate: arrayToTimestamp(decrypted.slice(150, 154)),
mac: uint8ArrayToString(decrypted.slice(154, 174)),
timezoneOffset: new Date().getTimezoneOffset() * 60
}
this.updateLockInfo({
featureValue: uint8ArrayToString(decrypted.slice(175, 175 + decrypted[174])),
featureSettingValue: uint8ArrayToString(
decrypted.slice(
176 + decrypted[174],
176 + decrypted[174] + decrypted[175 + decrypted[174]]
)
),
featureSettingParams: removeTrailingZeros(Array.from(
decrypted.slice(176 + decrypted[174] + decrypted[175 + decrypted[174]])
)),
lockConfig
})
console.log('获取锁状态成功', this.lockInfo.lockConfig)
2024-12-19 16:01:45 +08:00
}
this.characteristicValueCallback(new Result(decrypted[2]))
break
case cmdIds.addUser:
this.updateLockInfo({
token: decrypted.slice(42, 46)
})
if (decrypted[46] === Result.Success.code) {
this.updateLockInfo({
lockUserNo: decrypted[47] * 256 + decrypted[48]
})
2024-12-19 16:01:45 +08:00
}
console.log('添加用户结果', decrypted[46], this.lockInfo.lockUserNo)
this.characteristicValueCallback(new Result(decrypted[46]))
break
case cmdIds.expandCmd:
const subCmdId = decrypted[3]
switch (subCmdId) {
case subCmdIds.updateAdminPassword:
this.updateLockInfo({
token: decrypted.slice(5, 9)
})
if (decrypted[2] === Result.Success.code) {
const result = await changeAdminKeyboardPwdRequest({
password: this.requestParams.adminPwd,
lockId: this.lockInfo.lockId
})
return this.characteristicValueCallback(new Result(result.code))
}
this.characteristicValueCallback(new Result(decrypted[2]))
break
case subCmdIds.resetLockPassword:
this.updateLockInfo({
token: decrypted.slice(5, 9)
})
this.characteristicValueCallback(new Result(decrypted[4]))
break
case subCmdIds.setLockPassword:
this.updateLockInfo({
token: decrypted.slice(5, 9)
})
if (decrypted[2] === Result.Success.code) {
if (decrypted[11] === Result.Success.code) {
const pwdNo = decrypted[9] * 256 + decrypted[10]
if (this.requestParams.operate === 0) {
const addResult = await addCustomPasswordRequest({
...this.requestParams,
pwdUserNo: pwdNo,
lockId: this.lockInfo.lockId
})
if (addResult.code === Result.Success.code) {
this.characteristicValueCallback(
new Result(addResult.code, {
pwdNo,
keyboardPwdId: addResult.data.keyboardPwdId,
keyboardPwd: addResult.data.keyboardPwd,
keyboardPwdStatus: addResult.data.keyboardPwdStatus,
pwdUserNo: pwdNo
})
)
} else {
this.characteristicValueCallback(
new Result(addResult.code, addResult.data, addResult.message)
)
}
} else if (this.requestParams.operate === 1) {
const updateResult = await updatePasswordRequest(this.requestParams)
if (updateResult.code === Result.Success.code) {
this.characteristicValueCallback(new Result(updateResult.code))
} else {
this.characteristicValueCallback(
new Result(updateResult.code, updateResult.data, updateResult.message)
)
}
} else if (this.requestParams.operate === 2 || this.requestParams.operate === 3) {
const deleteResult = await deletePasswordRequest(this.requestParams)
if (deleteResult.code === Result.Success.code) {
this.characteristicValueCallback(new Result(deleteResult.code))
} else {
this.characteristicValueCallback(
new Result(deleteResult.code, deleteResult.data, deleteResult.message)
)
}
}
} else {
this.characteristicValueCallback(new Result(decrypted[11]))
}
} else {
this.characteristicValueCallback(new Result(decrypted[2]))
}
break
case subCmdIds.syncOpenRecord:
if (decrypted[2] === Result.Success.code && decrypted[6] > 0) {
const records = []
const count = decrypted[6] || 0
for (let i = 0; i < count; i++) {
let password = decrypted.slice(14 + 17 * i, 14 + 17 * i + 10)
if (password.every(item => item === 0)) {
password = null
} else {
password = uint8ArrayToString(password)
}
const record = {
type: decrypted[7 + 17 * i],
user: decrypted[8 + 17 * i] * 256 + decrypted[9 + 17 * i],
date: arrayToTimestamp(decrypted.slice(10 + 17 * i, 14 + 17 * i)) * 1000,
success: 1,
password
}
records.push(record)
}
const {code, message} = await uploadRecordRequest({
records,
lockId: this.lockInfo.lockId
})
this.characteristicValueCallback(
new Result(
code,
{
count
},
message
)
)
} else {
this.characteristicValueCallback(new Result(decrypted[2]))
}
break
case subCmdIds.registerCard:
if (decrypted[2] === Result.Success.code) {
// 锁版应答成功
switch (this.requestParams.operate) {
case 1:
// 修改
const updateResult = await updateIcCardRequest({
...this.requestParams,
cardId: this.requestParams.cardId,
cardRight: this.requestParams.isAdmin,
lockId: this.lockInfo.lockId,
2025-03-08 16:33:45 +08:00
cardNumber: this.requestParams.cardNumber,
cardType: this.requestParams.cardType,
cardUserNo: this.requestParams.cardUserNo
})
this.characteristicValueCallback(updateResult)
await this.disconnectDevice()
break;
case 2:
// 删除
const deleteResult = await deleteIcCardRequest({
cardId: this.requestParams.cardId,
lockId: this.lockInfo.lockId,
})
this.characteristicValueCallback(deleteResult)
await this.disconnectDevice()
break;
case 3:
// 删除全部
const deleteAllResult = await clearAllIcCard({
lockId: this.lockInfo.lockId,
})
this.characteristicValueCallback(deleteAllResult)
await this.disconnectDevice()
break;
default:
this.characteristicValueCallback(new Result(decrypted[2]))
break;
}
} else {
this.characteristicValueCallback(new Result(decrypted[2]))
}
break;
case subCmdIds.registerCardConfirm:
// 收到锁版回复判断操作类型进行对应api操作
if (decrypted[2] === Result.Success.code) {
if (decrypted[5] === Result.Success.code) {
switch (this.requestParams.operate) {
case 0:
// 注册
const addResult = await addIcCardRequest({
...this.requestParams,
isCoerced: this.requestParams.isForce,
cardRight: this.requestParams.isAdmin,
lockId: this.lockInfo.lockId,
cardNumber: decrypted[6] * 256 + decrypted[7],
cardUserNo: decrypted[6] * 256 + decrypted[7]
})
if (addResult.code === Result.Success.code) {
// 增加返回一个卡序号
addResult.data.cardNumber = decrypted[6] * 256 + decrypted[7];
}
// 触发卡片确认事件
emitRegisterCardConfirmEvent(addResult)
// 断开蓝牙连接
await this.disconnectDevice()
break;
}
} else {
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[5]))
this.characteristicValueCallback(new Result(decrypted[5]))
}
} else {
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[2]))
this.characteristicValueCallback(new Result(decrypted[2]))
}
break;
case subCmdIds.registerFingerprint:
if (decrypted[2] === Result.Success.code) {
// 锁版应答成功
switch (this.requestParams.operate) {
case 0:
// 注册开始返回最大注册次数
this.characteristicValueCallback(new Result(Result.Success.code, {
maxRegCount: decrypted[11],
}, Result.Success.message))
break;
case 1:
// 修改
const updateResult = await updateFingerprintRequest({
...this.requestParams,
fingerprintId: this.requestParams.fingerprintId,
fingerRight: this.requestParams.isAdmin
})
this.characteristicValueCallback(updateResult)
await this.disconnectDevice()
break;
case 2:
// 删除
const deleteResult = await deleteFingerprintRequest({
fingerprintId: this.requestParams.fingerprintId,
lockId: this.lockInfo.lockId,
2025-03-08 16:33:45 +08:00
fingerprintNumber: this.requestParams.fingerprintNumber,
deleteType: this.requestParams.deleteType || 1,
})
this.characteristicValueCallback(deleteResult)
await this.disconnectDevice()
break;
case 3:
// 删除全部
const deleteAllResult = await clearAllFingerprint({
lockId: this.lockInfo.lockId,
})
this.characteristicValueCallback(deleteAllResult)
await this.disconnectDevice()
break;
default:
this.characteristicValueCallback(new Result(decrypted[2]))
break;
}
} else {
this.characteristicValueCallback(new Result(decrypted[2]))
}
break;
case subCmdIds.registerFingerprintProcess:
emitRegisterFingerprintProcessEvent({
status: decrypted[5],
process: decrypted[6]
})
break;
case subCmdIds.registerFingerprintConfirm:
2025-03-08 16:33:45 +08:00
if (decrypted[2] === Result.Success.code) {
if (decrypted[5] === Result.Success.code) {
if (this.requestParams.operate === 0) {
switch (this.requestParams.operate) {
case 0:
const addResult = await addFingerprintRequest({
...this.requestParams,
isCoerced: this.requestParams.isForce,
fingerRight: this.requestParams.isAdmin,
lockId: this.lockInfo.lockId,
fingerprintNumber: decrypted[6] * 256 + decrypted[7],
fingerprintUserNo: decrypted[6] * 256 + decrypted[7]
})
if (addResult.code === Result.Success.code) {
// 增加返回一个指纹序号
addResult.data.fingerprintNumber = decrypted[6] * 256 + decrypted[7];
}
// 触发指纹确认事件
emitRegisterFingerprintConfirmEvent(addResult)
// 断开蓝牙连接
await this.disconnectDevice()
break;
}
2025-03-08 16:33:45 +08:00
}
} else {
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[5]))
this.characteristicValueCallback(new Result(decrypted[5]))
}
} else {
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[2]))
this.characteristicValueCallback(new Result(decrypted[2]))
}
break;
case subCmdIds.registerFace:
if (decrypted[2] === Result.Success.code) {
// 锁版应答成功
switch (this.requestParams.operate) {
case 0:
// 注册开始返回最大注册次数
this.characteristicValueCallback(new Result(Result.Success.code, {
maxRegCount: decrypted[11],
}, Result.Success.message))
break;
case 1:
// 修改
const updateResult = await updateFaceRequest({
...this.requestParams,
faceId: this.requestParams.faceId,
faceRight: this.requestParams.isAdmin
})
this.characteristicValueCallback(updateResult)
await this.disconnectDevice()
break;
case 2:
// 删除
const deleteResult = await deleteFaceRequest({
faceId: this.requestParams.faceId,
lockId: this.lockInfo.lockId,
})
this.characteristicValueCallback(deleteResult)
await this.disconnectDevice()
break;
case 3:
// 删除全部
const deleteAllResult = await clearAllFace({
lockId: this.lockInfo.lockId,
})
this.characteristicValueCallback(deleteAllResult)
await this.disconnectDevice()
break;
default:
this.characteristicValueCallback(new Result(decrypted[2]))
break;
}
} else {
this.characteristicValueCallback(new Result(decrypted[2]))
}
break;
case subCmdIds.registerFaceProcess:
emitRegisterFaceProcessEvent({
status: decrypted[5],
process: decrypted[6]
})
break;
case subCmdIds.registerFaceConfirm:
if (this.requestParams.operate === 0) {
if (decrypted[5] === Result.Success.code) {
switch (this.requestParams.operate) {
case 0:
const addResult = await addFaceRequest({
...this.requestParams,
isCoerced: this.requestParams.isForce,
fingerRight: this.requestParams.isAdmin,
lockId: this.lockInfo.lockId,
faceNumber: decrypted[6] * 256 + decrypted[7],
faceUserNo: decrypted[6] * 256 + decrypted[7]
})
if (addResult.code === Result.Success.code) {
// 增加返回一个序号
addResult.data.faceNumber = decrypted[6] * 256 + decrypted[7];
}
// 触发事件
emitRegisterFaceConfirmEvent(addResult)
// 断开蓝牙连接
await this.disconnectDevice()
break;
}
} else {
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[5]))
this.characteristicValueCallback(new Result(decrypted[5]))
}
} else {
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[2]))
this.characteristicValueCallback(new Result(decrypted[2]))
}
break;
2025-03-08 10:38:30 +08:00
case subCmdIds.registerPalmVein:
if (decrypted[2] === Result.Success.code) {
// 锁版应答成功
switch (this.requestParams.operate) {
case 1:
// 修改
const updateResult = await updatePalmVeinRequest({
...this.requestParams,
palmVeinId: this.requestParams.palmVeinId,
palmVeinRight: this.requestParams.isAdmin,
lockId: this.lockInfo.lockId,
palmVeinNumber: this.requestParams.palmVeinNumber,
palmVeinType: this.requestParams.palmVeinType,
palmVeinNo: this.requestParams.palmVeinNo
})
this.characteristicValueCallback(updateResult)
await this.disconnectDevice()
break;
case 2:
// 删除
const deleteResult = await deletePalmVeinRequest({
palmVeinId: this.requestParams.palmVeinId,
lockId: this.lockInfo.lockId,
})
this.characteristicValueCallback(deleteResult)
await this.disconnectDevice()
break;
case 3:
// 删除全部
const deleteAllResult = await clearAllPalmVein({
lockId: this.lockInfo.lockId,
})
this.characteristicValueCallback(deleteAllResult)
await this.disconnectDevice()
break;
default:
this.characteristicValueCallback(new Result(decrypted[2]))
break;
}
} else {
this.characteristicValueCallback(new Result(decrypted[2]))
2025-03-08 10:38:30 +08:00
}
break;
case subCmdIds.registerPalmVeinConfirm:
// 收到锁版回复判断操作类型进行对应api操作
if (decrypted[2] === Result.Success.code) {
if (decrypted[5] === Result.Success.code) {
switch (this.requestParams.operate) {
case 0:
// 注册
const addResult = await addPalmVeinRequest({
...this.requestParams,
isCoerced: this.requestParams.isForce,
palmVeinRight: this.requestParams.isAdmin,
lockId: this.lockInfo.lockId,
palmVeinNumber: decrypted[6] * 256 + decrypted[7],
palmVeinUserNo: decrypted[6] * 256 + decrypted[7]
})
if (addResult.code === Result.Success.code) {
// 增加返回一个卡序号
addResult.data.palmVeinNumber = decrypted[6] * 256 + decrypted[7];
}
// 触发卡片确认事件
emitRegisterPalmVeinConfirmEvent(addResult)
// 断开蓝牙连接
await this.disconnectDevice()
break;
}
} else {
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[5]))
this.characteristicValueCallback(new Result(decrypted[5]))
2025-03-08 10:50:25 +08:00
}
} else {
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[2]))
this.characteristicValueCallback(new Result(decrypted[2]))
2025-03-08 10:50:25 +08:00
}
break;
case subCmdIds.registerRemote:
if (decrypted[2] === Result.Success.code) {
// 锁版应答成功
switch (this.requestParams.operate) {
case 1:
// 修改
const updateResult = await updateRemoteRequest({
...this.requestParams,
remoteId: this.requestParams.remoteId,
remoteRight: this.requestParams.isAdmin,
lockId: this.lockInfo.lockId,
remoteType: this.requestParams.remoteType,
})
this.characteristicValueCallback(updateResult)
await this.disconnectDevice()
break;
case 2:
// 删除
const deleteResult = await deletePalmVeinRequest({
remoteId: this.requestParams.remoteId,
lockId: this.lockInfo.lockId,
})
this.characteristicValueCallback(deleteResult)
await this.disconnectDevice()
break;
case 3:
// 删除全部
const deleteAllResult = await clearAllPalmVein({
lockId: this.lockInfo.lockId,
})
this.characteristicValueCallback(deleteAllResult)
await this.disconnectDevice()
break;
default:
this.characteristicValueCallback(new Result(decrypted[2]))
break;
}
} else {
this.characteristicValueCallback(new Result(decrypted[2]))
2025-03-08 10:50:25 +08:00
}
break;
case subCmdIds.registerRemoteConfirm:
// 收到锁版回复判断操作类型进行对应api操作
if (decrypted[2] === Result.Success.code) {
if (decrypted[5] === Result.Success.code) {
switch (this.requestParams.operate) {
case 0:
// 注册
const addResult = await addRemoteRequest({
...this.requestParams,
isCoerced: this.requestParams.isForce,
remoteRight: this.requestParams.isAdmin,
lockId: this.lockInfo.lockId,
remoteNumber: decrypted[6] * 256 + decrypted[7],
remoteUserNo: decrypted[6] * 256 + decrypted[7]
})
if (addResult.code === Result.Success.code) {
// 增加返回一个卡序号
addResult.data.remoteNumber = decrypted[6] * 256 + decrypted[7];
}
// 触发卡片确认事件
emitRegisterRemoteConfirmEvent(addResult)
// 断开蓝牙连接
await this.disconnectDevice()
break;
}
} else {
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[5]))
this.characteristicValueCallback(new Result(decrypted[5]))
2025-03-08 10:38:30 +08:00
}
} else {
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[2]))
this.characteristicValueCallback(new Result(decrypted[2]))
2025-03-08 10:38:30 +08:00
}
break;
case subCmdIds.supportFunctionsWithParams:
// 收到锁版回复判断操作类型进行对应api操作
if (decrypted[2] === Result.Success.code) {
const {data, featureEnable} = this.requestParams
let updateResult = new Result();
switch (this.requestParams.featureBit) {
case supportFunctionsFeatureBit.passageMode:
updateResult = await updateLockSettingRequest({
lockId: this.lockInfo.lockId,
passageMode: data.passageMode,
passageModeConfig: [
{
startDate: data.startDate,
endDate: data.endDate,
isAllDay: data.isAllDay,
weekDays: data.weekDay,
autoUnlock: data.autoUnlock,
}
],
})
break;
case supportFunctionsFeatureBit.automaticLocking:
updateResult = await updateLockSettingRequest({
lockId: this.lockInfo.lockId,
autoLock: data > 0 ? 1 : 0,
autoLockSecond: data,
})
break;
case supportFunctionsFeatureBit.antiPrySwitch:
updateResult = await updateLockSettingRequest({
lockId: this.lockInfo.lockId,
antiPrySwitch: featureEnable
})
break;
case supportFunctionsFeatureBit.lockSound:
updateResult = await updateLockSettingRequest({
lockId: this.lockInfo.lockId,
lockSound: data > 0 ? 1 : 0,
lockSoundVolume: data,
})
break;
default:
this.characteristicValueCallback(new Result(decrypted[2]))
break;
}
this.characteristicValueCallback(new Result(updateResult.code))
} else {
this.characteristicValueCallback(new Result(decrypted[2]))
}
break;
case subCmdIds.supportFunctions:
// 收到锁版回复判断操作类型进行对应api操作
if (decrypted[2] === Result.Success.code) {
const {data, featureEnable} = this.requestParams
let updateResult = new Result();
switch (this.requestParams.featureBit) {
case supportFunctionsFeatureBit.antiPrySwitch:
updateResult = await updateLockSettingRequest({
lockId: this.lockInfo.lockId,
antiPrySwitch: featureEnable
})
break;
default:
this.characteristicValueCallback(new Result(decrypted[2]))
break;
}
this.characteristicValueCallback(new Result(updateResult.code))
} else {
this.characteristicValueCallback(new Result(decrypted[2]))
}
break;
default:
this.characteristicValueCallback(new Result(decrypted[2]))
break
2024-12-19 16:01:45 +08:00
}
break
case cmdIds.openDoor:
this.updateLockInfo({
token: decrypted.slice(2, 6),
electricQuantity: decrypted[7],
electricQuantityStandby: decrypted[9]
})
if (decrypted[6] === Result.Success.code) {
updateElectricQuantityRequest({
lockId: this.lockInfo.lockId,
electricQuantity: decrypted[7],
electricQuantityStandby: decrypted[9]
}).then(() => {
})
}
this.characteristicValueCallback(new Result(decrypted[6], {lock: this.lockInfo}))
break
case cmdIds.resetDevice:
this.updateLockInfo({
token: decrypted.slice(2, 6)
})
if (decrypted[6] === Result.Success.code) {
const {code, message} = await deleteLockRequest({
lockId: this.lockInfo.lockId
})
if (code === Result.Success.code) {
const lockList = getStorage('starLockList')
if (lockList[this.accountInfo.uid]) {
const index = lockList[this.accountInfo.uid].findIndex(
item => item.lockId === this.lockInfo.lockId
)
if (index !== -1) {
lockList[this.accountInfo.uid].splice(index, 1)
}
setStorage('starLockList', lockList)
}
}
this.characteristicValueCallback(new Result(code, {}, message))
} else {
this.characteristicValueCallback(new Result(decrypted[6]))
}
break
2025-06-11 17:29:21 +08:00
case cmdIds.searchWiFiResult:
if (decrypted[2] === Result.Success.code) {
const wifiInfoList = parseWifiList(decrypted);
emitSearchWiFiResultEventUni({
code: wifiInfoList.status,
numberOfSsid: wifiInfoList.numberOfSsid,
wifiList: wifiInfoList.wifiList,
})
}
break;
case cmdIds.configureNetworkResult:
if (decrypted[2] === Result.Success.code) {
// 提取配网信息
const {
peerId,
wifiName,
secretKey,
deviceMac,
networkMac
} = parseNetworkJsonFromDecrypted(decrypted);
const {code, message} = await updateDeviceNetworkInfo({
deviceType: 2, // 1-wifi网关 2-wifi锁
deviceMac: deviceMac || this.lockInfo.mac,
wifiName: wifiName || this.requestParams.wifiName,
networkMac: networkMac || this.requestParams.wifiName,
secretKey,
peerId
});
if (code === Result.Success.code) {
this.characteristicValueCallback(new Result(decrypted[2], null, "配网成功"))
} else {
this.characteristicValueCallback(code, null, message);
}
2025-06-11 17:29:21 +08:00
} else {
this.characteristicValueCallback(new Result(decrypted[2], null, "配网失败"))
}
break;
default:
this.updateLockInfo({
token: decrypted.slice(2, 6)
})
console.log('默认结果', decrypted[6], this.lockInfo.token)
this.characteristicValueCallback(new Result(decrypted[6]))
break
2024-12-19 16:01:45 +08:00
}
}
}
// 获取配置
export function getConfig() {
2024-12-26 15:10:01 +08:00
const config = this.env === "LOCAL" ? {
name: 'LOCAL',
baseUrl: this.clientUrl
} : configs[this.env];
2024-12-26 15:04:30 +08:00
return {
...config,
version,
buildNumber
}
2024-12-19 16:01:45 +08:00
}
/*
* 生成包头
* encryptionType 加密类型 0明文1AES1282SM4事先约定密钥3SM4设备指定密钥
* originalLength 原始数据长度
* */
export function 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
2024-12-19 16:01:45 +08:00
}
2024-12-19 16:01:45 +08:00
// 断开与设备的连接
export async function disconnectDevice() {
return await closeBLEConnection(this.lockInfo.deviceId)
2024-12-19 16:01:45 +08:00
}
2025-03-27 17:50:38 +08:00