import 'dart:async'; import 'dart:convert'; import 'dart:typed_data'; import 'package:flutter/material.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; 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 bool, String deviceId) { if (!_tcpClient.isConnected) { debugPrint('❌sendSwitchControlResponse [TCP] 无法发送权限响应:Socket 未连接'); throw Exception('sendSwitchControlResponse TCP 未连接'); } try { // 构造响应 JSON(参考 Android 代码) final response = bool ? { 'respond': { 'switchResult': true, 'deviceId': deviceId, 'holder': 'you', }, } : { 'respond': { 'switchResult': false, 'deviceId': deviceId, 'reason': 'holder_denied', }, }; if(!bool){ debugPrint('sendSwitchControlResponse[TCP] 拒绝授权:$deviceId'); }else{ debugPrint('sendSwitchControlResponse[TCP] 同意授权:$deviceId'); } //debugPrint('sendSwitchControlResponse[TCP] 同意授权:$deviceId'); final jsonStr = jsonEncode(response); final jsonBytes = utf8.encode(jsonStr); debugPrint('sendSwitchControlResponse[TCP] 响应权限请求:$jsonStr'); // 构造完整的协议包 final packet = buildSwitchControlPacket(jsonBytes); debugPrint('sendSwitchControlResponse[TCP] 完整数据包:${packet.map((b) => '0x${b.toRadixString(16)}').join(' ')}'); // 发送数据包 _tcpClient.sendnew(packet); } catch (e) { debugPrint('❌ sendSwitchControlResponse[TCP] 响应权限请求失败:$e'); rethrow; } } }