// DFU (Device Firmware Update) 工具类 // 用于处理设备固件升级过程 import supa, { supaReady } from '@/components/supadb/aksupainstance.uts' export type FirmwareInfo { version: string url: string size: number checksum: string description?: string } //https://ak3.oulog.com/storage/v1/object/public/akmon/OmFw2510221553.zip export type FirmwareConfig { default_value: string default_key?: string } export type DFUProgress { stage: 'downloading' | 'verifying' | 'uploading' | 'upgrading' | 'completed' progress: number // 0-100 message: string } export class DFUTool { private progressCallback?: (progress: DFUProgress) => void constructor(progressCallback?: (progress: DFUProgress) => void) { this.progressCallback = progressCallback } /** * 检查是否有可用的固件升级 * @param currentHardwareVersion 当前硬件版本 * @param currentSoftwareVersion 当前软件版本 * @returns 固件信息或null */ async checkFirmwareUpdate(currentHardwareVersion: string, currentSoftwareVersion: string): Promise { try { // 从Supabase查询最新固件版本 const result = await supa .from('ak_global_config') .select('default_value,default_key', {}) .eq('config_key', 'cfwatch_hardware_version') .single() .executeAs() console.log(result.data) const data = result.data as FirmwareConfig if (result.error !=null ) { console.log('查询固件版本失败:', result.error) return null } const firmwareConfig = data // 比较版本号,检查是否需要升级 if (this.compareVersions(currentSoftwareVersion, firmwareConfig.default_value) < 0) { return { version: firmwareConfig.default_value, url: firmwareConfig.default_key, size: 0, checksum: '', description: '' } } return null } catch (error) { console.error('检查固件升级失败:', error) return null } } /** * 执行固件升级 * @param firmwareInfo 固件信息 * @param deviceId 设备ID * @returns 升级结果 */ async performFirmwareUpdate(firmwareInfo: FirmwareInfo, deviceId: string): Promise { try { this.updateProgress('downloading', 0, '开始下载固件...') // 下载固件文件 const firmwareData = await this.downloadFirmware(firmwareInfo.url) this.updateProgress('verifying', 50, '验证固件完整性...') // 验证文件完整性 if (!this.verifyFirmware(firmwareData, firmwareInfo.checksum)) { throw new Error('固件校验失败') } this.updateProgress('uploading', 70, '上传固件到设备...') // 执行DFU升级 const success = await this.executeDFU(firmwareData, deviceId) if (success) { this.updateProgress('completed', 100, '固件升级完成') return true } else { throw new Error('DFU升级失败') } } catch (error) { console.error('固件升级失败:', error) this.updateProgress('completed', 0, `升级失败: ${error}`) return false } } /** * 下载固件文件 */ private async downloadFirmware(url: string): Promise { return new Promise((resolve, reject) => { uni.downloadFile({ url: url, success: (res) => { if (res.statusCode === 200) { // 读取下载的文件 uni.getFileSystemManager().readFile({ filePath: res.tempFilePath, success: (readRes) => { resolve(readRes.data as ArrayBuffer) }, fail: reject }) } else { reject(new Error(`下载失败: ${res.statusCode}`)) } }, fail: reject }) }) } /** * 验证固件完整性 */ private verifyFirmware(data: ArrayBuffer, expectedChecksum: string): boolean { // 简单的校验和验证(可以根据需要实现更复杂的校验) const hash = this.calculateSimpleHash(data) return hash === expectedChecksum } /** * 执行DFU升级 */ private async executeDFU(firmwareData: ArrayBuffer, deviceId: string): Promise { // 这里实现具体的DFU协议 // 需要根据设备的DFU协议来实现 // 这是一个简化的实现,实际需要根据具体设备协议调整 try { // 1. 进入DFU模式 await this.enterDFUMode(deviceId) // 2. 发送固件数据包 await this.sendFirmwarePackets(firmwareData, deviceId) // 3. 验证升级结果 await this.verifyUpdate(deviceId) return true } catch (error) { console.error('DFU执行失败:', error) return false } } /** * 进入DFU模式 */ private async enterDFUMode(deviceId: string): Promise { // 实现进入DFU模式的逻辑 // 通常需要发送特定的命令到设备 } /** * 发送固件数据包 */ private async sendFirmwarePackets(firmwareData: ArrayBuffer, deviceId: string): Promise { // 实现分包发送固件的逻辑 const packetSize = 20 // 根据设备协议调整 const totalPackets = Math.ceil(firmwareData.byteLength / packetSize) for (let i = 0; i < totalPackets; i++) { const start = i * packetSize const end = Math.min(start + packetSize, firmwareData.byteLength) const packet = firmwareData.slice(start, end) // 发送数据包 await this.sendPacket(packet, deviceId) // 更新进度 const progress = Math.round((i + 1) / totalPackets * 100) this.updateProgress('uploading', 70 + (progress * 0.2), `上传进度: ${i + 1}/${totalPackets}`) } } /** * 发送单个数据包 */ private async sendPacket(packet: ArrayBuffer, deviceId: string): Promise { // 实现BLE发送数据包的逻辑 } /** * 验证升级结果 */ private async verifyUpdate(deviceId: string): Promise { // 实现验证升级结果的逻辑 } /** * 计算简单校验和 */ private calculateSimpleHash(data: ArrayBuffer): string { const view = new Uint8Array(data) let hash = 0 for (let i = 0; i < view.length; i++) { hash = ((hash << 5) - hash + view[i]) & 0xffffffff } return hash.toString(16) } /** * 比较版本号 */ private compareVersions(version1: string, version2: string): number { const v1Parts = version1.split('.').map((item) => parseInt(item)) const v2Parts = version2.split('.').map((item) => parseInt(item)) for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) { const v1 = v1Parts[i] != null ? v1Parts[i] : 0 const v2 = v2Parts[i] != null ? v2Parts[i] : 0 if (v1 > v2) return 1 if (v1 < v2) return -1 } return 0 } /** * 更新进度 */ private updateProgress(stage: 'downloading' | 'verifying' | 'uploading' | 'upgrading' | 'completed', progress: number, message: string): void { if (this.progressCallback != null) { this.progressCallback({ stage, progress: Math.min(100, Math.max(0, progress)), message }) } } } // 导出单例实例 export const dfuTool = new DFUTool(null)