Files
flutterApp/lib/features/remote_control/data/datasources/remote_tcp_datasource.dart

157 lines
5.5 KiB
Dart
Raw Normal View History

import 'dart:async';
import 'dart:convert';
2026-03-16 15:31:14 +08:00
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<void> sendSwitchControlRequest(String deviceName) async {
if (!_tcpClient.isConnected) {
2026-03-16 15:31:14 +08:00
debugPrint('❌sendSwitchControlRequest [TCP] 无法发送权限请求:Socket 未连接');
throw Exception('sendSwitchControlRequest TCP 未连接');
}
try {
// 获取用户信息
final user = await _userStorage.getUser();
if (user == null || user.token == null) {
2026-03-16 15:31:14 +08:00
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);
2026-03-16 15:31:14 +08:00
debugPrint('sendSwitchControlRequest[TCP] 发送权限请求指令:$jsonStr');
debugPrint('sendSwitchControlRequest[TCP] 发送权限请求指令:$jsonBytes');
// 使用 0x12 指令发送(cmdGetAuth)
// 注意:根据你的协议文档,这里可能是 0x04 或 0x12
// Android 代码中使用的是 0x12
2026-03-16 15:31:14 +08:00
// _tcpClient.sendnew(
// // MachineProtocolConstants.cmdGetAuth, // 0x04 或 0x12,根据实际协议调整
// jsonBytes,
// );
// 构造完整的协议包
final packet = buildSwitchControlPacket(jsonBytes);
2026-03-16 15:31:14 +08:00
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) {
2026-03-16 15:31:14 +08:00
debugPrint('❌ sendSwitchControlRequest[TCP] 发送权限请求失败:$e');
rethrow;
}
}
/// 监听 TCP 回包流
/// 用于接收权限响应、状态更新等
Stream<RawPacket> get responseStream => _tcpClient.packetStream;
/// 检查 TCP 连接状态
bool get isConnected => _tcpClient.isConnected;
2026-03-16 15:31:14 +08:00
/// 构建 switch_control 协议包
///
/// 包结构:
/// - 帧头:0xAB, 0xAA (2 字节)
/// - 命令字:0x12 (1 字节)
/// - 数据载荷:JSON UTF-8 字节 (N 字节)
/// - 帧尾:0x00, 0x00, 0xAA, 0xAB (4 字节)
List<int> buildSwitchControlPacket(List<int> 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;
}
}
}