2025-03-07 11:13:13 +08:00
|
|
|
|
import {sm4} from 'sm-crypto'
|
2024-12-19 16:01:45 +08:00
|
|
|
|
import {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
arrayToTimestamp,
|
|
|
|
|
|
convertWeekdaysToNumber,
|
|
|
|
|
|
createPackageEnd,
|
2025-07-01 11:46:05 +08:00
|
|
|
|
md5Encrypt, parseNetworkJsonFromDecrypted, parseWifiList,
|
2025-03-07 11:13:13 +08:00
|
|
|
|
removeTrailingZeros,
|
|
|
|
|
|
timestampToArray,
|
|
|
|
|
|
uint8ArrayToString
|
2024-12-19 16:01:45 +08:00
|
|
|
|
} from './format'
|
2025-03-07 11:13:13 +08:00
|
|
|
|
import {configs} from './env'
|
2025-04-10 15:01:55 +08:00
|
|
|
|
import {cmdIds, Result, subCmdIds, supportFunctionsFeatureBit} from './constant'
|
2024-12-19 16:01:45 +08:00
|
|
|
|
import {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
closeBLEConnection,
|
|
|
|
|
|
searchAndConnectDevice,
|
|
|
|
|
|
writeBLECharacteristicValue
|
2024-12-20 09:01:21 +08:00
|
|
|
|
} from './uni/basic'
|
2024-12-19 16:01:45 +08:00
|
|
|
|
import {
|
2025-03-08 10:17:29 +08:00
|
|
|
|
addCustomPasswordRequest, addFaceRequest,
|
|
|
|
|
|
addFingerprintRequest,
|
2025-03-08 10:50:25 +08:00
|
|
|
|
addIcCardRequest, addPalmVeinRequest, addRemoteRequest,
|
2025-03-08 10:17:29 +08:00
|
|
|
|
changeAdminKeyboardPwdRequest, clearAllFace,
|
|
|
|
|
|
clearAllFingerprint,
|
2025-03-08 10:38:30 +08:00
|
|
|
|
clearAllIcCard, clearAllPalmVein,
|
2025-03-08 10:17:29 +08:00
|
|
|
|
deleteFaceRequest,
|
|
|
|
|
|
deleteFingerprintRequest,
|
|
|
|
|
|
deleteIcCardRequest,
|
2025-03-08 10:38:30 +08:00
|
|
|
|
deleteLockRequest, deletePalmVeinRequest,
|
2025-03-07 11:13:13 +08:00
|
|
|
|
deletePasswordRequest,
|
|
|
|
|
|
getLastRecordTimeRequest,
|
|
|
|
|
|
getLockNetTokenRequest,
|
|
|
|
|
|
getStarCloudToken,
|
2025-07-01 11:46:05 +08:00
|
|
|
|
getUserNoListRequest, updateDeviceNetworkInfo,
|
2025-03-08 10:17:29 +08:00
|
|
|
|
updateElectricQuantityRequest,
|
|
|
|
|
|
updateFaceRequest,
|
|
|
|
|
|
updateFingerprintRequest,
|
2025-04-10 15:01:55 +08:00
|
|
|
|
updateIcCardRequest, updateLockSettingRequest,
|
2025-03-08 10:38:30 +08:00
|
|
|
|
updateLockUserNoRequest, updatePalmVeinRequest,
|
2025-03-08 10:50:25 +08:00
|
|
|
|
updatePasswordRequest, updateRemoteRequest,
|
2025-03-07 11:13:13 +08:00
|
|
|
|
uploadRecordRequest
|
2024-12-19 16:01:45 +08:00
|
|
|
|
} from './api'
|
2025-03-07 11:13:13 +08:00
|
|
|
|
import {
|
|
|
|
|
|
buildNumber,
|
2025-03-08 10:50:25 +08:00
|
|
|
|
emitRegisterCardConfirmEvent,
|
|
|
|
|
|
emitRegisterFaceConfirmEvent,
|
|
|
|
|
|
emitRegisterFaceProcessEvent,
|
|
|
|
|
|
emitRegisterFingerprintConfirmEvent,
|
|
|
|
|
|
emitRegisterFingerprintProcessEvent,
|
|
|
|
|
|
emitRegisterPalmVeinConfirmEvent,
|
|
|
|
|
|
emitRegisterRemoteConfirmEvent,
|
2025-03-07 11:13:13 +08:00
|
|
|
|
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) {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
// 设置执行账号
|
|
|
|
|
|
const result = await this.login(params.uid)
|
|
|
|
|
|
if (result.code !== Result.Success.code) {
|
|
|
|
|
|
return result
|
2024-12-19 16:01:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-07 11:13:13 +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
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
// 检查是否已添加为用户
|
|
|
|
|
|
const checkResult = await this.checkLockUser()
|
|
|
|
|
|
if (checkResult.code !== Result.Success.code) {
|
|
|
|
|
|
return checkResult
|
|
|
|
|
|
}
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +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
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
const timeResult = await getLastRecordTimeRequest({
|
|
|
|
|
|
lockId: this.lockInfo.lockId
|
|
|
|
|
|
})
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
if (timeResult.code !== Result.Success.code) {
|
|
|
|
|
|
return timeResult
|
|
|
|
|
|
}
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +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
|
|
|
|
|
2025-03-07 11:13:13 +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
|
|
|
|
|
2025-03-07 11:13:13 +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
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
// 子命令
|
|
|
|
|
|
contentArray[2] = subCmdIds.syncOpenRecord
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
contentArray[3] = length - 3
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
for (let i = 0; i < keyId.length; i++) {
|
|
|
|
|
|
contentArray[i + 4] = keyId.charCodeAt(i)
|
|
|
|
|
|
}
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
for (let i = 0; i < uid.length; i++) {
|
|
|
|
|
|
contentArray[i + 44] = uid.charCodeAt(i)
|
|
|
|
|
|
}
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
contentArray[64] = logsCount / 256
|
|
|
|
|
|
contentArray[65] = logsCount % 256
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
contentArray.set(timestampToArray(operateDate), 66)
|
|
|
|
|
|
contentArray.set(timestampToArray(currentDate), 70)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
contentArray[74] = 16
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +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
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
contentArray.set(md5Array, 75)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +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
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
const writeResult = await writeBLECharacteristicValue(
|
|
|
|
|
|
this.lockInfo.deviceId,
|
|
|
|
|
|
this.lockInfo.serviceId,
|
|
|
|
|
|
this.lockInfo.writeCharacteristicId,
|
|
|
|
|
|
packageArray
|
|
|
|
|
|
)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
if (writeResult.code !== Result.Success.code) {
|
|
|
|
|
|
return writeResult
|
|
|
|
|
|
}
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
return this.getWriteResult(this.syncOpenRecord, params)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 清理用户
|
|
|
|
|
|
* @returns {Promise<Result>}
|
|
|
|
|
|
*/
|
|
|
|
|
|
export async function cleanLockUser() {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
// 确认设备连接正常
|
|
|
|
|
|
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
|
2025-03-24 15:26:37 +08:00
|
|
|
|
* @param {Boolean} [force] 是否强制更新
|
2024-12-20 17:36:14 +08:00
|
|
|
|
* @returns Result
|
2024-12-19 16:01:45 +08:00
|
|
|
|
*/
|
2025-03-24 15:26:37 +08:00
|
|
|
|
export async function login(uid, force = false) {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
let accounts = getStorage('starCloudAccount')
|
|
|
|
|
|
let userInfos = getStorage('starCloudUser')
|
|
|
|
|
|
if (!accounts) {
|
|
|
|
|
|
accounts = {}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!userInfos) {
|
|
|
|
|
|
userInfos = {}
|
|
|
|
|
|
}
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
const id = uid || this.accounts[0].uid
|
|
|
|
|
|
this.accountInfo = accounts[id]
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
if (this.accountInfo) {
|
2025-03-24 15:26:37 +08:00
|
|
|
|
if (this.accountInfo.token && !force) {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
this.userInfo = userInfos[id]
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
setStorage('starCloudToken', this.accountInfo.token)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +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
|
|
|
|
}
|
2025-03-07 11:13:13 +08:00
|
|
|
|
return Result.Fail
|
2024-12-19 16:01:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取公钥
|
|
|
|
|
|
export async function getPublicKey() {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
const headArray = this.createPackageHeader(0, 42)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
const contentArray = new Uint8Array(42)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
contentArray[0] = cmdIds.getPublicKey / 256
|
|
|
|
|
|
contentArray[1] = cmdIds.getPublicKey % 256
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
const name = this.lockInfo.bluetooth.bluetoothDeviceName
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
for (let i = 0; i < name.length; i++) {
|
|
|
|
|
|
contentArray[i + 2] = name.charCodeAt(i)
|
|
|
|
|
|
}
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
const packageArray = createPackageEnd(headArray, contentArray)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
const writeResult = await writeBLECharacteristicValue(
|
|
|
|
|
|
this.lockInfo.deviceId,
|
|
|
|
|
|
this.lockInfo.serviceId,
|
|
|
|
|
|
this.lockInfo.writeCharacteristicId,
|
|
|
|
|
|
packageArray
|
|
|
|
|
|
)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
if (writeResult.code !== Result.Success.code) {
|
|
|
|
|
|
return writeResult
|
|
|
|
|
|
}
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
return this.getWriteResult(this.getPublicKey, {disconnect: false})
|
2024-12-19 16:01:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取私钥
|
|
|
|
|
|
export async function getCommKey() {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
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
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
contentArray[0] = cmdIds.getCommKey / 256
|
|
|
|
|
|
contentArray[1] = cmdIds.getCommKey % 256
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +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
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
for (let i = 0; i < name.length; i++) {
|
|
|
|
|
|
contentArray[i + 2] = name.charCodeAt(i)
|
|
|
|
|
|
}
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
for (let i = 0; i < keyId.length; i++) {
|
|
|
|
|
|
contentArray[i + 42] = keyId.charCodeAt(i)
|
|
|
|
|
|
}
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
for (let i = 0; i < authUid.length; i++) {
|
|
|
|
|
|
contentArray[i + 82] = authUid.charCodeAt(i)
|
|
|
|
|
|
}
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
contentArray.set(timestampToArray(nowTime), 102)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
contentArray[106] = 16
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
const md5Array = md5Encrypt(
|
|
|
|
|
|
authUid + keyId,
|
|
|
|
|
|
contentArray.slice(102, 106),
|
|
|
|
|
|
this.lockInfo.bluetooth.publicKey
|
|
|
|
|
|
)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
contentArray.set(md5Array, 107)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
const cebArray = sm4.encrypt(contentArray, contentArray.slice(2, 18), {
|
|
|
|
|
|
mode: 'ecb',
|
|
|
|
|
|
output: 'array'
|
|
|
|
|
|
})
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
const packageArray = createPackageEnd(headArray, cebArray)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
const writeResult = await writeBLECharacteristicValue(
|
|
|
|
|
|
this.lockInfo.deviceId,
|
|
|
|
|
|
this.lockInfo.serviceId,
|
|
|
|
|
|
this.lockInfo.writeCharacteristicId,
|
|
|
|
|
|
packageArray
|
|
|
|
|
|
)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
if (writeResult.code !== Result.Success.code) {
|
|
|
|
|
|
return writeResult
|
|
|
|
|
|
}
|
2024-12-19 16:01:45 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
return this.getWriteResult(this.getCommKey, {disconnect: false})
|
2024-12-19 16:01:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取锁状态
|
|
|
|
|
|
export async function getLockStatus() {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
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() {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
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) {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
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
|
|
|
|
|
2025-03-07 11:13:13 +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
|
|
|
|
)
|
2025-03-07 11:13:13 +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
|
|
|
|
}
|
2025-03-07 11:13:13 +08:00
|
|
|
|
return this.getWriteResult(this.addLockUser, params)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取写入结果
|
|
|
|
|
|
export function getWriteResult(request, params) {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
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
|
|
|
|
}
|
2025-03-07 11:13:13 +08:00
|
|
|
|
})
|
2024-12-19 16:01:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否已添加为用户
|
|
|
|
|
|
export async function checkLockUser(forceAdd = false) {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
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
|
|
|
|
}
|
2025-03-07 11:13:13 +08:00
|
|
|
|
return Result.Success
|
2024-12-19 16:01:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新锁信息
|
|
|
|
|
|
export function updateLockInfo(lockInfo) {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
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) {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
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(() => {
|
|
|
|
|
|
})
|
2025-03-07 18:10:07 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
} 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) {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
// 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]))
|
|
|
|
|
|
// }
|
2025-03-07 11:13:13 +08:00
|
|
|
|
} 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
|
|
|
|
}
|
2025-03-07 11:13:13 +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)
|
2025-03-07 11:13:13 +08:00
|
|
|
|
|
|
|
|
|
|
if (decrypted[0] * 256 + decrypted[1] === cmdIds.getCommKey) {
|
2024-12-19 16:01:45 +08:00
|
|
|
|
if (decrypted[2] === Result.Success.code) {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
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]))
|
2025-03-07 11:13:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
const cebBinaryData = binaryData.slice(12, binaryData.length - 2)
|
|
|
|
|
|
const decrypted = sm4.decrypt(cebBinaryData, this.lockInfo.bluetooth.privateKey, {
|
|
|
|
|
|
mode: 'ecb',
|
2025-03-07 18:10:07 +08:00
|
|
|
|
output: 'array',
|
|
|
|
|
|
padding: 'none'
|
2025-03-07 11:13:13 +08:00
|
|
|
|
})
|
2025-06-11 17:29:21 +08:00
|
|
|
|
console.log('SM4(设备指定密钥) ecb解密后的数据', decrypted)
|
2025-03-07 11:13:13 +08:00
|
|
|
|
|
|
|
|
|
|
const cmdId = decrypted[0] * 256 + decrypted[1]
|
|
|
|
|
|
|
2025-04-07 11:18:38 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
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
|
|
|
|
}
|
2025-03-07 11:13:13 +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
|
|
|
|
}
|
2025-03-07 11:13:13 +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)
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
2025-04-07 11:18:38 +08:00
|
|
|
|
} else if (this.requestParams.operate === 2 || this.requestParams.operate === 3) {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
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,
|
2025-03-07 11:13:13 +08:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
2025-04-10 15:01:55 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
this.characteristicValueCallback(new Result(decrypted[2]))
|
2025-03-07 11:13:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case subCmdIds.registerCardConfirm:
|
|
|
|
|
|
// 收到锁版回复判断操作类型进行对应api操作
|
|
|
|
|
|
if (decrypted[2] === Result.Success.code) {
|
2025-06-16 10:06:21 +08:00
|
|
|
|
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],
|
2025-09-19 11:29:22 +08:00
|
|
|
|
cardUserNo: decrypted[6] * 256 + decrypted[7]
|
2025-06-16 10:06:21 +08:00
|
|
|
|
})
|
|
|
|
|
|
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]))
|
2025-03-07 11:13:13 +08:00
|
|
|
|
}
|
2025-04-10 15:01:55 +08:00
|
|
|
|
} else {
|
2025-06-12 17:29:09 +08:00
|
|
|
|
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[2]))
|
2025-04-10 15:01:55 +08:00
|
|
|
|
this.characteristicValueCallback(new Result(decrypted[2]))
|
2025-03-07 11:13:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case subCmdIds.registerFingerprint:
|
2025-03-07 18:10:07 +08:00
|
|
|
|
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,
|
2025-03-07 18:10:07 +08:00
|
|
|
|
})
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
2025-04-10 15:01:55 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
this.characteristicValueCallback(new Result(decrypted[2]))
|
2025-03-07 18:10:07 +08:00
|
|
|
|
}
|
2025-03-07 11:13:13 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case subCmdIds.registerFingerprintProcess:
|
2025-03-07 18:10:07 +08:00
|
|
|
|
emitRegisterFingerprintProcessEvent({
|
|
|
|
|
|
status: decrypted[5],
|
|
|
|
|
|
process: decrypted[6]
|
|
|
|
|
|
})
|
2025-03-07 11:13:13 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case subCmdIds.registerFingerprintConfirm:
|
2025-03-08 16:33:45 +08:00
|
|
|
|
if (decrypted[2] === Result.Success.code) {
|
2025-06-16 10:06:21 +08:00
|
|
|
|
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],
|
2025-09-19 11:29:22 +08:00
|
|
|
|
fingerprintUserNo: decrypted[6] * 256 + decrypted[7]
|
2025-06-16 10:06:21 +08:00
|
|
|
|
})
|
|
|
|
|
|
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
|
|
|
|
}
|
2025-06-16 10:06:21 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[5]))
|
|
|
|
|
|
this.characteristicValueCallback(new Result(decrypted[5]))
|
2025-03-07 11:13:13 +08:00
|
|
|
|
}
|
2025-06-16 10:06:21 +08:00
|
|
|
|
|
2025-04-10 15:01:55 +08:00
|
|
|
|
} else {
|
2025-06-12 17:29:09 +08:00
|
|
|
|
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[2]))
|
2025-04-10 15:01:55 +08:00
|
|
|
|
this.characteristicValueCallback(new Result(decrypted[2]))
|
2025-03-08 10:17:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
2025-04-10 15:01:55 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
this.characteristicValueCallback(new Result(decrypted[2]))
|
2025-03-08 10:17:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case subCmdIds.registerFaceProcess:
|
|
|
|
|
|
emitRegisterFaceProcessEvent({
|
|
|
|
|
|
status: decrypted[5],
|
|
|
|
|
|
process: decrypted[6]
|
|
|
|
|
|
})
|
|
|
|
|
|
break;
|
|
|
|
|
|
case subCmdIds.registerFaceConfirm:
|
|
|
|
|
|
if (this.requestParams.operate === 0) {
|
2025-06-16 10:06:21 +08:00
|
|
|
|
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],
|
2025-09-19 11:29:22 +08:00
|
|
|
|
faceUserNo: decrypted[6] * 256 + decrypted[7]
|
2025-06-16 10:06:21 +08:00
|
|
|
|
})
|
|
|
|
|
|
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]))
|
2025-03-08 10:17:29 +08:00
|
|
|
|
}
|
2025-04-10 15:01:55 +08:00
|
|
|
|
} else {
|
2025-06-12 17:29:09 +08:00
|
|
|
|
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[2]))
|
2025-04-10 15:01:55 +08:00
|
|
|
|
this.characteristicValueCallback(new Result(decrypted[2]))
|
2025-03-07 11:13:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
2025-04-10 15:01:55 +08:00
|
|
|
|
} 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) {
|
2025-06-16 10:06:21 +08:00
|
|
|
|
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],
|
2025-09-19 11:29:22 +08:00
|
|
|
|
palmVeinUserNo: decrypted[6] * 256 + decrypted[7]
|
2025-06-16 10:06:21 +08:00
|
|
|
|
})
|
|
|
|
|
|
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
|
|
|
|
}
|
2025-04-10 15:01:55 +08:00
|
|
|
|
} else {
|
2025-06-12 17:29:09 +08:00
|
|
|
|
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[2]))
|
2025-04-10 15:01:55 +08:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
2025-04-10 15:01:55 +08:00
|
|
|
|
} 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) {
|
2025-06-16 10:06:21 +08:00
|
|
|
|
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],
|
2025-09-19 11:29:22 +08:00
|
|
|
|
remoteUserNo: decrypted[6] * 256 + decrypted[7]
|
2025-06-16 10:06:21 +08:00
|
|
|
|
})
|
|
|
|
|
|
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
|
|
|
|
}
|
2025-06-16 10:06:21 +08:00
|
|
|
|
|
2025-04-10 15:01:55 +08:00
|
|
|
|
} else {
|
2025-06-12 17:29:09 +08:00
|
|
|
|
emitRegisterCardConfirmEvent(new Result(Result.Fail.code, null, decrypted[2]))
|
2025-04-10 15:01:55 +08:00
|
|
|
|
this.characteristicValueCallback(new Result(decrypted[2]))
|
2025-03-08 10:38:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
2025-04-10 15:01:55 +08:00
|
|
|
|
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: [
|
|
|
|
|
|
{
|
2025-04-15 15:21:17 +08:00
|
|
|
|
startDate: data.startDate,
|
|
|
|
|
|
endDate: data.endDate,
|
2025-04-10 15:01:55 +08:00
|
|
|
|
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:
|
2025-04-15 15:21:17 +08:00
|
|
|
|
// 收到锁版回复判断操作类型进行对应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]))
|
|
|
|
|
|
}
|
2025-04-10 15:01:55 +08:00
|
|
|
|
break;
|
2025-03-07 11:13:13 +08:00
|
|
|
|
default:
|
2025-06-12 17:29:09 +08:00
|
|
|
|
this.characteristicValueCallback(new Result(decrypted[2]))
|
2025-03-07 11:13:13 +08:00
|
|
|
|
break
|
2024-12-19 16:01:45 +08:00
|
|
|
|
}
|
2025-03-07 11:13:13 +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) {
|
2025-07-01 11:46:05 +08:00
|
|
|
|
// 提取配网信息
|
|
|
|
|
|
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;
|
2025-03-07 11:13:13 +08:00
|
|
|
|
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
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
const config = this.env === "LOCAL" ? {
|
|
|
|
|
|
name: 'LOCAL',
|
|
|
|
|
|
baseUrl: this.clientUrl
|
|
|
|
|
|
} : configs[this.env];
|
2024-12-26 15:04:30 +08:00
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
return {
|
|
|
|
|
|
...config,
|
|
|
|
|
|
version,
|
|
|
|
|
|
buildNumber
|
|
|
|
|
|
}
|
2024-12-19 16:01:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* 生成包头
|
|
|
|
|
|
* encryptionType 加密类型 0:明文,1:AES128,2:SM4(事先约定密钥),3:SM4(设备指定密钥)
|
|
|
|
|
|
* originalLength 原始数据长度
|
|
|
|
|
|
* */
|
|
|
|
|
|
export function createPackageHeader(encryptionType, originalLength) {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
// 头部数据
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-07 11:13:13 +08:00
|
|
|
|
|
2024-12-19 16:01:45 +08:00
|
|
|
|
// 断开与设备的连接
|
|
|
|
|
|
export async function disconnectDevice() {
|
2025-03-07 11:13:13 +08:00
|
|
|
|
return await closeBLEConnection(this.lockInfo.deviceId)
|
2024-12-19 16:01:45 +08:00
|
|
|
|
}
|
2025-03-27 17:50:38 +08:00
|
|
|
|
|
2025-04-10 15:01:55 +08:00
|
|
|
|
|