import 'dart:async'; import 'dart:convert'; import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; import '../../../../core/logging/i_logger_service.dart'; import '../../../../core/network/protocol_decoder.dart'; import '../../../../core/network/tcp/tcp_client.dart'; import '../../../../core/protocol/machine_protocol_constants.dart'; import '../../../../core/storage/user_storage.dart'; /// 远程遥控 TCP 数据源 /// 负责通过 TCP 协议发送控制指令和权限请求 class RemoteTcpDatasource { final TcpClient _tcpClient; final UserStorage _userStorage; final ILoggerService _logger = GetIt.I(); RemoteTcpDatasource(this._tcpClient, this._userStorage); /// 发送 switch_control 权限请求(对应 Android 的 requestSwitchControl) /// /// 这是获取设备控制权的第一步: /// 1. 先发送 TCP 0x12 指令携带 switch_control 请求 /// 2. 等待服务端响应 /// 3. 再调用 HTTP API 确认控制权 Future sendSwitchControlRequest(String deviceName) async { if (!_tcpClient.isConnected) { debugPrint('❌sendSwitchControlRequest [TCP] 无法发送权限请求:Socket 未连接'); throw Exception('sendSwitchControlRequest TCP 未连接'); } try { // 获取用户信息 final user = await _userStorage.getUser(); if (user == null || user.token == null) { debugPrint( '❌ sendSwitchControlRequest[TCP] 认证失败:用户未登录或 Token 为空,无法发送认证包', ); throw Exception('用户未登录或 Token 无效'); } final username = user.username; final token = user.token; final currentDeviceId = deviceName; // 构造 JSON 请求体(参考 Android 代码) final request = { 'request': 'switch_control', 'deviceId': currentDeviceId, 'userId': username, 'platform': 'app', 'token': token, }; final jsonStr = jsonEncode(request); final jsonBytes = utf8.encode(jsonStr); debugPrint('sendSwitchControlRequest[TCP] 发送权限请求指令:$jsonStr'); debugPrint('sendSwitchControlRequest[TCP] 发送权限请求指令:$jsonBytes'); // 使用 0x12 指令发送(cmdGetAuth) // 注意:根据你的协议文档,这里可能是 0x04 或 0x12 // Android 代码中使用的是 0x12 // _tcpClient.sendnew( // // MachineProtocolConstants.cmdGetAuth, // 0x04 或 0x12,根据实际协议调整 // jsonBytes, // ); // 构造完整的协议包 final packet = buildSwitchControlPacket(jsonBytes); debugPrint( 'sendSwitchControlRequest[TCP] 完整数据包:${packet.map((b) => '0x${b.toRadixString(16)}').join(' ')}', ); // 发送数据包 _tcpClient.sendnew(packet); debugPrint( '✅ sendSwitchControlRequest[TCP] 已发送 switch_control 权限请求 (0x${MachineProtocolConstants.cmdGetAuth.toRadixString(16)})', ); } catch (e) { debugPrint('❌ sendSwitchControlRequest[TCP] 发送权限请求失败:$e'); rethrow; } } /// 监听 TCP 回包流 /// 用于接收权限响应、状态更新等 Stream get responseStream => _tcpClient.packetStream; /// 检查 TCP 连接状态 bool get isConnected => _tcpClient.isConnected; /// 构建 switch_control 协议包 /// /// 包结构: /// - 帧头:0xAB, 0xAA (2 字节) /// - 命令字:0x12 (1 字节) /// - 数据载荷:JSON UTF-8 字节 (N 字节) /// - 帧尾:0x00, 0x00, 0xAA, 0xAB (4 字节) List buildSwitchControlPacket(List jsonBytes) { final builder = BytesBuilder() ..addByte(MachineProtocolConstants.header1) // 0xAB ..addByte(MachineProtocolConstants.header2) // 0xAA ..addByte(0x12) // 命令字:switch_control ..add(jsonBytes) // JSON 数据 ..addByte(0x00) // CRC 占位 1 ..addByte(0x00) // CRC 占位 2 ..addByte(MachineProtocolConstants.endFlag1) // 0xAA ..addByte(MachineProtocolConstants.endFlag2); // 0xAB return builder.takeBytes(); } // TODO: 同意授权和拒绝授权 void sendSwitchControlResponse(bool agreed, String deviceId) { debugPrint( '📤 [进入了TCP层==== 被调用 - agreed=$agreed, deviceId=$deviceId', ); // 🔥 添加详细的连接状态日志 debugPrint( '📤 [进入了TCP层==== 当前 TCP 连接状态: isConnected=${_tcpClient.isConnected}', ); if (!_tcpClient.isConnected) { debugPrint('❌ [TCP DataSource] 无法发送权限响应: Socket 未连接'); debugPrint('❌ [TCP DataSource] isConnected=${_tcpClient.isConnected}'); throw Exception('sendSwitchControlResponse TCP 未连接'); } try { debugPrint('📡 [TCP DataSource] TCP 连接正常,准备发送数据...'); // 构造响应 JSON(参考 Android 代码) final response = agreed ? { 'respond': { 'switchResult': true, 'deviceId': deviceId, 'holder': 'you', }, } : { 'respond': { 'switchResult': false, 'deviceId': deviceId, 'reason': 'holder_denied', }, }; debugPrint( '📝 [TCP DataSource] ${agreed ? "同意" : "拒绝"}授权: deviceId=$deviceId', ); final jsonStr = jsonEncode(response); final jsonBytes = utf8.encode(jsonStr); debugPrint('📦 [TCP DataSource] JSON 数据: $jsonStr'); debugPrint('📦 [TCP DataSource] JSON 字节长度: ${jsonBytes.length} 字节'); // 构造完整的协议包 final packet = buildSwitchControlPacket(jsonBytes); _logger.logWithLevel('TCP DataSource] JSON 数据: $jsonStr' ,shouldLog: true); debugPrint( '📦 [TCP DataSource] 完整数据包(${packet.length}字节): ${packet.map((b) => '0x${b.toRadixString(16).padLeft(2, "0")}').join(' ')}', ); // 🔥 发送前再次检查连接状态 if (!_tcpClient.isConnected) { debugPrint('❌ [TCP DataSource] 发送前检查: Socket 已断开连接!'); throw Exception('TCP 连接在发送前断开'); } // 发送数据包 debugPrint('🚀 [TCP DataSource] 正在调用 SendNew 发送数据...'); // 🔥 添加详细日志:记录发送的完整数据包(十六进制) final hexString = packet .map((byte) => '0x${byte.toRadixString(16).padLeft(2, '0')}') .join(' '); debugPrint('📦 [TCP DataSource] 完整数据包(${packet.length}字节): $hexString'); // 🔥 使用ILoggerService记录日志 _logger.logWithLevel( '📦 [TCP DataSource] 完整数据包(${packet.length}字节): $hexString', shouldLog: true, ); // 🔥 记录JSON内容和字节数 _logger.logWithLevel( '📝 [TCP DataSource] 发送内容: $jsonStr', shouldLog: true, ); _logger.logWithLevel( '📊 [TCP DataSource] JSON字节数: ${jsonBytes.length}, 完整包字节数: ${packet.length}', shouldLog: true, ); _tcpClient.sendnew(packet); debugPrint('✅ [TCP DataSource] TCP 响应已成功发送'); debugPrint('✅ [TCP DataSource] 发送字节数: ${packet.length}'); // 🔥 发送成功后的日志 _logger.logWithLevel( '✅ [TCP DataSource] TCP 响应已成功发送 - agreed=$agreed, deviceId=$deviceId, 字节数=${packet.length}', shouldLog: true, ); } catch (e) { debugPrint('❌ [TCP DataSource] 响应权限请求失败: $e'); debugPrint('❌ [TCP DataSource] 错误类型: ${e.runtimeType}'); debugPrint('❌ [TCP DataSource] 错误堆栈: ${StackTrace.current}'); rethrow; } } }