import 'dart:convert'; import 'package:starwork_flutter/base/app_logger.dart'; import 'package:starwork_flutter/ble/ble_service.dart'; import 'package:starwork_flutter/ble/command/base/base_ble_command.dart'; import 'package:starwork_flutter/ble/command/base/base_ble_response_parser.dart'; import 'package:starwork_flutter/ble/command/response/ble_cmd_get_private_key_parser.dart'; import 'package:starwork_flutter/ble/command/response/ble_cmd_get_public_key_parser.dart'; import 'package:starwork_flutter/common/sm4_encipher/sm4.dart'; /// ✨✨✨ 蓝牙命令管理器 - 统一管理所有命令解析器 ✨✨✨ class BleCommandManager { // 私有构造函数 BleCommandManager._() { // ✅ 这里就是单例初始化的地方 // 只会执行一次(第一次获取实例时) _initialize(); } // 单例实例 static final BleCommandManager _instance = BleCommandManager._(); // 工厂构造函数,提供全局访问点 factory BleCommandManager() => _instance; /// 所有已注册的命令解析器 final Map _parsers = {}; /// ✨✨✨ 初始化命令管理器 ✨✨✨ void _initialize() { AppLogger.highlight('✨✨✨ 🚀 初始化蓝牙命令管理器 ✨✨✨'); // 注册所有命令解析器 _registerParsers(); AppLogger.info('📋 已注册命令解析器数量: ${_parsers.length}'); _parsers.forEach((commandId, parser) { AppLogger.debug(' • 0x${commandId.toRadixString(16).padLeft(4, '0')}: ${parser.commandName}'); }); AppLogger.highlight('✨✨✨ ✅ 蓝牙命令管理器初始化完成 ✨✨✨'); } /// ✨✨✨ 注册所有命令解析器 ✨✨✨ void _registerParsers() { // 注册获取公钥命令解析器 registerParser(BleCmdGetPublicKeyParser()); registerParser(BleCmdGetPrivateKeyParser()); // TODO: 在这里注册其他命令解析器 // registerParser(BleCmdSetPasswordParser()); // registerParser(BleCmdUnlockParser()); // 等等... } /// ✨✨✨ 注册命令解析器 ✨✨✨ void registerParser(BaseBleResponseParser parser) { _parsers[parser.commandId] = parser; AppLogger.debug('📝 注册命令解析器: 0x${parser.commandId.toRadixString(16).padLeft(4, '0')} - ${parser.commandName}'); } /// ✨✨✨ 移除命令解析器 ✨✨✨ void unregisterParser(int commandId) { BaseBleResponseParser? removed = _parsers.remove(commandId); if (removed != null) { AppLogger.debug('🗑️ 移除命令解析器: 0x${commandId.toRadixString(16).padLeft(4, '0')} - ${removed.commandName}'); } } /// ✨✨✨ 处理接收到的应答数据包 ✨✨✨ /// [rawPacketData] 完整的原始数据包 /// 返回解析后的业务数据,如果没有匹配的解析器则返回null dynamic handleResponse(List rawPacketData) { AppLogger.debug('📊 收到蓝牙数据 (${rawPacketData.length}字节): ${rawPacketData.map((b) => '0x${b.toRadixString(16).padLeft(2, '0')}').join(' ')}'); try { // ✨✨✨ 首先解析数据包以获取命令ID ✨✨✨ var parsedPacket = BaseBleCommand.parsePacket(rawPacketData); // 检查数据包是否有效 if (!parsedPacket.isValid) { AppLogger.warn('⚠️ 数据包无效: ${parsedPacket.errorMessage}'); return null; } // 检查数据长度是否足够包含命令ID if (parsedPacket.data.length < 2) { AppLogger.warn('⚠️ 应答数据长度不足,无法包含命令ID: ${parsedPacket.data.length}字节'); return null; } // ✨✨✨ 根据加密类型进行解密处理 ✨✨✨ List processedData = _decryptDataIfNeeded(parsedPacket); // ✨✨✨ 提取命令ID (大端序) ✨✨✨ int commandId = (processedData[0] << 8) | processedData[1]; AppLogger.debug('🔍 提取命令ID: 0x${commandId.toRadixString(16).padLeft(4, '0')}'); // ✨✨✨ 直接通过命令ID查找对应的解析器 ✨✨✨ BaseBleResponseParser? parser = _parsers[commandId]; if (parser != null) { AppLogger.debug('🎯 找到匹配的解析器: ${parser.commandName}'); // 创建一个新的ParsedPacket对象,使用解密后的数据 ParsedPacket decryptedPacket = ParsedPacket( isValid: parsedPacket.isValid, packetType: parsedPacket.packetType, packetSequence: parsedPacket.packetSequence, version: parsedPacket.version, encryptType: parsedPacket.encryptType, encryptedDataLength: parsedPacket.encryptedDataLength, originalDataLength: parsedPacket.originalDataLength, data: processedData, crc16: parsedPacket.crc16, errorMessage: parsedPacket.errorMessage, ); // 传递解密后的数据给解析器 dynamic result = parser.parseResponse(decryptedPacket, processedData); return result; } else { // 没有找到匹配的解析器 AppLogger.warn('⚠️ 未找到命令ID 0x${commandId.toRadixString(16).padLeft(4, '0')} 对应的解析器'); _logUnknownPacket(rawPacketData); return null; } } catch (e, stackTrace) { AppLogger.error('❌ 处理蓝牙应答异常', error: e, stackTrace: stackTrace); return null; } } /// ✨✨✨ 根据加密类型解密数据 ✨✨✨ /// [parsedPacket] 已解析的数据包 /// 返回解密后的数据或原始数据(如果不需要解密) List _decryptDataIfNeeded(ParsedPacket parsedPacket) { // 如果是明文,直接返回原始数据 if (parsedPacket.encryptType == BaseBleCommand.ENCRYPT_TYPE_PLAIN) { AppLogger.debug('🔓 数据未加密,直接使用原始数据'); return parsedPacket.data; } switch (parsedPacket.encryptType) { case BaseBleCommand.ENCRYPT_TYPE_AES128: return _decryptAES128(parsedPacket.data); case BaseBleCommand.ENCRYPT_TYPE_SM4_PRESET: var decrypt = SM4.decrypt( parsedPacket.data, key: utf8.encode('TMH_190068d76ae8'), mode: SM4CryptoMode.ECB, ); return decrypt; case BaseBleCommand.ENCRYPT_TYPE_SM4_DEVICE: return _decryptSM4(parsedPacket.data); default: AppLogger.warn('⚠️ 未知的加密类型: ${parsedPacket.encryptType},使用原始数据'); return parsedPacket.data; } } /// ✨✨✨ AES128解密 ✨✨✨ /// [encryptedData] 加密数据 /// 返回解密后的数据 List _decryptAES128(List encryptedData) { // TODO: 实现AES128解密逻辑 return encryptedData; } /// ✨✨✨ SM4解密 ✨✨✨ /// [encryptedData] 加密数据 /// 返回解密后的数据 List _decryptSM4(List encryptedData) { return encryptedData; } /// ✨✨✨ 根据命令ID获取解析器 ✨✨✨ BaseBleResponseParser? getParser(int commandId) { return _parsers[commandId]; } /// ✨✨✨ 获取所有已注册的命令ID ✨✨✨ List getRegisteredCommandIds() { return _parsers.keys.toList(); } /// ✨✨✨ 获取所有已注册的解析器信息 ✨✨✨ Map getRegisteredParsersInfo() { return _parsers.map((commandId, parser) => MapEntry(commandId, parser.commandName)); } /// ✨✨✨ 记录未知数据包信息 ✨✨✨ void _logUnknownPacket(List rawPacketData) { try { // 尝试基本解析以获取更多信息 var parsedPacket = BaseBleCommand.parsePacket(rawPacketData); if (parsedPacket.isValid && parsedPacket.data.length >= 2) { int commandId = (parsedPacket.data[0] << 8) | parsedPacket.data[1]; AppLogger.warn('🔍 未知命令应答: 命令ID=0x${commandId.toRadixString(16).padLeft(4, '0')}, ' + '包类型=0x${parsedPacket.packetType.toRadixString(16).padLeft(2, '0')}, ' + '数据长度=${parsedPacket.data.length}字节'); } else { AppLogger.warn('🔍 无效或无法识别的数据包'); } } catch (e) { AppLogger.warn('🔍 无法解析的数据包: $e'); } } /// ✨✨✨ 清除所有解析器 ✨✨✨ void clear() { AppLogger.info('🧹 清除所有命令解析器'); _parsers.clear(); } /// ✨✨✨ 重新初始化 ✨✨✨ void reinitialize() { AppLogger.info('🔄 重新初始化命令管理器'); clear(); _initialize(); } }