app-starlock/lib/talk/startChart/command/message_command.dart

497 lines
15 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:convert';
import 'dart:typed_data';
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart';
import 'package:star_lock/talk/startChart/constant/protocol_flag_constant.dart';
import 'package:star_lock/talk/startChart/constant/udp_constant.dart';
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
import 'package:star_lock/talk/startChart/proto/ble_message.pb.dart';
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
import 'package:star_lock/talk/startChart/proto/rbcu.pb.dart';
import 'package:star_lock/talk/startChart/proto/talk_accept.pb.dart';
import 'package:star_lock/talk/startChart/proto/talk_expect.pb.dart';
import 'package:star_lock/talk/startChart/proto/talk_hangup.pb.dart';
import 'package:star_lock/talk/startChart/proto/talk_ping.pb.dart';
import 'package:star_lock/talk/startChart/proto/talk_reject.pb.dart';
import 'package:star_lock/talk/startChart/proto/talk_request.pb.dart';
class MessageCommand {
// 全局字典,用于存储每个 ToPeerId 对应的当前 messageId
// 单个会话的messageId需要递增
static Map<String, int> _messageIdMap = {};
static int _maxIntValue = 9223372036854775807; // Dart 中 int 的最大值
// 获取并递增消息ID
static int getNextMessageId(String toPeerId, {bool increment = true}) {
if (_messageIdMap.containsKey(toPeerId)) {
if (increment) {
_messageIdMap[toPeerId] = _messageIdMap[toPeerId]! + 1;
// 如果 messageId 超过 int 的最大值,则重置为 1
if (_messageIdMap[toPeerId]! > _maxIntValue) {
_messageIdMap[toPeerId] = 1;
}
}
} else {
_messageIdMap[toPeerId] = 1;
}
return _messageIdMap[toPeerId]!;
}
/// 客户端去中继上线命令
static List<int> goOnlineRelay({
required String FromPeerId,
required String ToPeerId,
int? MessageId,
}) {
String serializedBytesString = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.Req,
MessageId: MessageId,
SpTotal: 1,
SpIndex: 1,
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
PayloadCRC: 0,
PayloadLength: 0,
PayloadType: PayloadTypeConstant.goOnline,
).serialize();
return _hexToBytes(serializedBytesString);
}
// 回声测试消息
static List<int> echoMessage({
required String ToPeerId,
required String FromPeerId,
List<int>? payload,
int? SpTotal,
int? SpIndex,
int? MessageId,
}) {
ScpMessage message = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.Req,
MessageId: MessageId,
SpTotal: SpTotal,
SpIndex: SpIndex,
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
Payload: payload,
PayloadCRC: calculationCrcFromIntList(payload ?? []),
PayloadLength: payload?.length ?? 0,
PayloadType: PayloadTypeConstant.echoTest,
);
String serializedBytesString = message.serialize();
return _hexToBytes(serializedBytesString);
}
// 心跳消息
static List<int> heartbeatMessage({
required String FromPeerId,
required String ToPeerId,
int? MessageId,
}) {
String payload = 'hello';
ScpMessage message = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.Req,
MessageId: MessageId,
SpTotal: 1,
SpIndex: 1,
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
Payload: payload,
PayloadCRC: calculationCrc(_stringToUint8List(payload)),
PayloadLength: payload.length,
PayloadType: PayloadTypeConstant.heartbeat,
);
String serializedBytesString = message.serialize();
return _hexToBytes(serializedBytesString);
}
// 网关初始化
static List<int> gatewayResetMessage({
required int gatewayId,
required String FromPeerId,
required String ToPeerId,
required int time,
int? MessageId,
}) {
// 构建荷载
final gatewayResetReq = GatewayResetReq(
iD: gatewayId,
time: time,
);
// 构建荷载长度
final payload = gatewayResetReq.writeToBuffer();
ScpMessage message = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.Req,
MessageId: MessageId,
SpTotal: 1,
SpIndex: 1,
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
Payload: payload,
PayloadCRC: calculationCrc(payload),
PayloadLength: payload.length,
PayloadType: PayloadTypeConstant.gatewayReset,
);
String serializedBytesString = message.serialize();
return _hexToBytes(serializedBytesString);
}
// 同意接听消息
static List<int> talkAcceptMessage({
required String FromPeerId,
required String ToPeerId,
int? MessageId,
}) {
final talkAcceptReq = TalkAcceptReq();
final payload = talkAcceptReq.writeToBuffer();
ScpMessage message = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.Req,
MessageId: MessageId,
SpTotal: 1,
SpIndex: 1,
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
Payload: payload,
PayloadCRC: calculationCrc(payload),
PayloadLength: payload.length,
PayloadType: PayloadTypeConstant.talkAccept,
);
String serializedBytesString = message.serialize();
return _hexToBytes(serializedBytesString);
}
// 发送对话请求消息
static List<int> talkRequestMessage({
required String FromPeerId,
required String ToPeerId,
int? MessageId,
}) {
final talkReq = TalkReq();
final payload = talkReq.writeToBuffer();
ScpMessage message = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.Req,
MessageId: MessageId,
SpTotal: 1,
SpIndex: 1,
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
Payload: payload,
PayloadCRC: calculationCrc(payload),
PayloadLength: payload.length,
PayloadType: PayloadTypeConstant.callRequest,
);
String serializedBytesString = message.serialize();
return _hexToBytes(serializedBytesString);
}
// 拒绝接听消息
static List<int> talkRejectMessage({
required String FromPeerId,
required String ToPeerId,
int? MessageId,
}) {
final talkReject = TalkReject();
final payload = talkReject.writeToBuffer();
ScpMessage message = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.Req,
MessageId: MessageId,
SpTotal: 1,
SpIndex: 1,
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
Payload: payload,
PayloadCRC: calculationCrc(payload),
PayloadLength: payload.length,
PayloadType: PayloadTypeConstant.talkReject,
);
String serializedBytesString = message.serialize();
return _hexToBytes(serializedBytesString);
}
// 呼叫保持消息
static List<int> talkPingMessage({
required String FromPeerId,
required String ToPeerId,
int? MessageId,
}) {
final talkPing = TalkPing();
final payload = talkPing.writeToBuffer();
ScpMessage message = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.Req,
MessageId: MessageId,
SpTotal: 1,
SpIndex: 1,
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
Payload: payload,
PayloadCRC: calculationCrc(payload),
PayloadLength: payload.length,
PayloadType: PayloadTypeConstant.talkPing,
);
String serializedBytesString = message.serialize();
return _hexToBytes(serializedBytesString);
}
// 通话中挂断
static List<int> talkHangupMessage({
required String FromPeerId,
required String ToPeerId,
int? MessageId,
}) {
final talkHangup = TalkHangup();
final payload = talkHangup.writeToBuffer();
ScpMessage message = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.Req,
MessageId: MessageId,
SpTotal: 1,
SpIndex: 1,
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
Payload: payload,
PayloadCRC: calculationCrc(payload),
PayloadLength: payload.length,
PayloadType: PayloadTypeConstant.talkHangup,
);
String serializedBytesString = message.serialize();
return _hexToBytes(serializedBytesString);
}
// 音视频数据
static List<int> talkDataMessage({
required String FromPeerId,
required String ToPeerId,
int? MessageId,
List<int>? payload,
int? SpTotal,
int? SpIndex,
}) {
// final payload = talkData.writeToBuffer();
ScpMessage message = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.RealTimeData,
MessageId: MessageId,
SpTotal: 1,
SpIndex: 1,
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
Payload: payload,
PayloadCRC: calculationCrc(Uint8List.fromList(payload!)),
PayloadLength: payload.length,
PayloadType: PayloadTypeConstant.talkData,
);
String serializedBytesString = message.serialize();
return _hexToBytes(serializedBytesString);
}
// 预期接收消息
static List<int> talkExpectMessage({
required String FromPeerId,
required String ToPeerId,
required TalkExpectReq talkExpect,
int? MessageId,
}) {
final payload = talkExpect.writeToBuffer();
ScpMessage message = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.Req,
MessageId: MessageId,
SpTotal: 1,
SpIndex: 1,
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
Payload: payload,
PayloadCRC: calculationCrc(payload),
PayloadLength: payload.length,
PayloadType: PayloadTypeConstant.talkExpect,
);
String serializedBytesString = message.serialize();
return _hexToBytes(serializedBytesString);
}
// GenericRespSuccess 消息
static List<int> genericRespSuccessMessage({
required String FromPeerId,
required String ToPeerId,
required int PayloadType,
int? MessageId,
}) {
final genericResp = GenericResp();
genericResp.message = UdpConstant.genericRespSuccessMsg;
genericResp.code = UdpConstant.genericRespSuccessCode;
final payload = genericResp.writeToBuffer();
ScpMessage message = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.Resp,
MessageId: MessageId,
SpTotal: 1,
SpIndex: 1,
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
Payload: payload,
PayloadCRC: calculationCrc(payload),
PayloadLength: payload.length,
PayloadType: PayloadType,
);
String serializedBytesString = message.serialize();
return _hexToBytes(serializedBytesString);
}
// GenericRespError 消息
static List<int> genericRespErrorMessage({
required String FromPeerId,
required String ToPeerId,
required int PayloadType,
int? MessageId,
String? errorMessageText,
}) {
final genericResp = GenericResp();
genericResp.message = errorMessageText ?? UdpConstant.genericRespErrorMsg;
genericResp.code = UdpConstant.genericRespErrorCode;
final payload = genericResp.writeToBuffer();
ScpMessage message = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.Resp,
MessageId: MessageId,
SpTotal: 1,
SpIndex: 1,
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
Payload: payload,
PayloadCRC: calculationCrc(payload),
PayloadLength: payload.length,
PayloadType: PayloadType,
);
String serializedBytesString = message.serialize();
return _hexToBytes(serializedBytesString);
}
// RbcuInfo 地址交换消息
static List<int> genericRbcuInfoMessage({
required String FromPeerId,
required String ToPeerId,
required RbcuInfo rbcuInfo,
int? MessageId,
String? errorMessageText,
}) {
final payload = rbcuInfo.writeToBuffer();
ScpMessage message = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.Req,
MessageId: MessageId,
SpTotal: 1,
SpIndex: 1,
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
Payload: payload,
PayloadCRC: calculationCrc(payload),
PayloadLength: payload.length,
PayloadType: PayloadTypeConstant.RbcuInfo,
);
String serializedBytesString = message.serialize();
return _hexToBytes(serializedBytesString);
}
// 蓝牙消息
static List<int> bleMessage({
required String FromPeerId,
required String ToPeerId,
required String bluetoothDeviceName,
required List<int> bleStructData,
int? MessageId,
int? timeout = 30,
int? IdleTimeout = 0,
}) {
final bleReq = BleReq(
bluetoothDeviceName: bluetoothDeviceName,
structData: bleStructData,
timeout: timeout,
idleTimeout: 0,
);
final payload = bleReq.writeToBuffer();
ScpMessage message = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.Req,
MessageId: MessageId,
SpTotal: 1,
SpIndex: 1,
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
Payload: payload,
PayloadCRC: calculationCrc(Uint8List.fromList(payload)),
PayloadLength: payload.length,
PayloadType: PayloadTypeConstant.blePassthrough,
);
String serializedBytesString = message.serialize();
return _hexToBytes(serializedBytesString);
}
// 辅助方法将16进制字符串转换为字节列表
static List<int> _hexToBytes(String hex) {
final bytes = <int>[];
for (int i = 0; i < hex.length; i += 2) {
bytes.add(int.parse(hex.substring(i, i + 2), radix: 16));
}
return bytes;
}
static int calculationCrc(Uint8List uint8Payload) {
// 使用自定义 CRC32 算法
final int crc32Value = _crc32Uint16(uint8Payload);
return crc32Value;
}
// 重载的方法,接受 List<int>
static int calculationCrcFromIntList(List<int> intList) {
// 将 List<int> 转换为 Uint8List
final Uint8List uint8Payload = Uint8List.fromList(intList);
// 调用现有的 calculationCrc 方法
return calculationCrc(uint8Payload);
}
// 将字符串转换为 Uint8List
static Uint8List _stringToUint8List(String input) {
return Uint8List.fromList(utf8.encode(input));
}
// 自定义 CRC32 实现
static int _crc32Uint16(Uint8List data) {
const int polynomial = 0xD5828281;
// 创建 CRC32 表
final List<int> table = List<int>.generate(256, (i) {
int crc = i;
for (int j = 0; j < 8; j++) {
if ((crc & 1) != 0) {
crc = (crc >> 1) ^ polynomial;
} else {
crc >>= 1;
}
}
return crc;
});
// 计算 CRC32 校验值
int crc = 0xFFFFFFFF;
for (final int byte in data) {
crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF];
}
crc ^= 0xFFFFFFFF;
// 返回 CRC32 的低 16 位
return crc & 0xFFFF;
}
}