339 lines
10 KiB
Dart
339 lines
10 KiB
Dart
import 'dart:convert';
|
||
import 'dart:typed_data';
|
||
|
||
import 'package:crc32_checksum/crc32_checksum.dart';
|
||
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/entity/scp_message.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/talk_accept.pb.dart';
|
||
import 'package:star_lock/talk/startChart/proto/talk_data.pb.dart';
|
||
import 'package:star_lock/talk/startChart/proto/talk_expect.pb.dart';
|
||
import 'package:star_lock/talk/startChart/proto/talk_ping.pb.dart';
|
||
import 'package:star_lock/talk/startChart/proto/talk_reject.pb.dart';
|
||
|
||
class MessageCommand {
|
||
/// 客户端去中继上线命令
|
||
static List<int> goOnlineRelay({
|
||
required String FromPeerId,
|
||
required String ToPeerId,
|
||
}) {
|
||
String serializedBytesString = ScpMessage(
|
||
ProtocolFlag: ProtocolFlagConstant.scp01,
|
||
MessageType: MessageTypeConstant.Req,
|
||
MessageId: 1,
|
||
SpTotal: 0,
|
||
SpIndex: 0,
|
||
FromPeerId: FromPeerId,
|
||
ToPeerId: ToPeerId,
|
||
Payload: 'hello',
|
||
PayloadCRC: 55230,
|
||
PayloadLength: 5,
|
||
PayloadType: PayloadTypeConstant.goOnline,
|
||
).serialize();
|
||
return _hexToBytes(serializedBytesString);
|
||
}
|
||
|
||
// 回声测试消息
|
||
static List<int> echoMessage({
|
||
required String ToPeerId,
|
||
required String FromPeerId,
|
||
}) {
|
||
String payload = 'hello';
|
||
ScpMessage message = ScpMessage(
|
||
ProtocolFlag: ProtocolFlagConstant.scp01,
|
||
MessageType: MessageTypeConstant.Req,
|
||
MessageId: 1,
|
||
SpTotal: 0,
|
||
SpIndex: 0,
|
||
FromPeerId: FromPeerId,
|
||
ToPeerId: ToPeerId,
|
||
Payload: payload,
|
||
PayloadCRC: calculationCrc(_stringToUint8List(payload)),
|
||
PayloadLength: payload.length,
|
||
PayloadType: PayloadTypeConstant.echoTest,
|
||
);
|
||
String serializedBytesString = message.serialize();
|
||
return _hexToBytes(serializedBytesString);
|
||
}
|
||
|
||
// 心跳消息
|
||
static List<int> heartbeatMessage({
|
||
required String FromPeerId,
|
||
required String ToPeerId,
|
||
}) {
|
||
String payload = 'hello';
|
||
ScpMessage message = ScpMessage(
|
||
ProtocolFlag: ProtocolFlagConstant.scp01,
|
||
MessageType: MessageTypeConstant.Req,
|
||
MessageId: 1,
|
||
SpTotal: 0,
|
||
SpIndex: 0,
|
||
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,
|
||
}) {
|
||
// 构建荷载
|
||
final gatewayResetReq = GatewayResetReq(
|
||
iD: gatewayId,
|
||
time: time,
|
||
);
|
||
// 构建荷载长度
|
||
final payload = gatewayResetReq.writeToBuffer();
|
||
ScpMessage message = ScpMessage(
|
||
ProtocolFlag: ProtocolFlagConstant.scp01,
|
||
MessageType: MessageTypeConstant.Req,
|
||
MessageId: 1,
|
||
SpTotal: 0,
|
||
SpIndex: 0,
|
||
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,
|
||
}) {
|
||
final talkAcceptReq = TalkAcceptReq();
|
||
final payload = talkAcceptReq.writeToBuffer();
|
||
ScpMessage message = ScpMessage(
|
||
ProtocolFlag: ProtocolFlagConstant.scp01,
|
||
MessageType: MessageTypeConstant.Req,
|
||
MessageId: 1,
|
||
SpTotal: 0,
|
||
SpIndex: 0,
|
||
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> talkRejectMessage({
|
||
required String FromPeerId,
|
||
required String ToPeerId,
|
||
}) {
|
||
final talkReject = TalkReject();
|
||
final payload = talkReject.writeToBuffer();
|
||
ScpMessage message = ScpMessage(
|
||
ProtocolFlag: ProtocolFlagConstant.scp01,
|
||
MessageType: MessageTypeConstant.Req,
|
||
MessageId: 1,
|
||
SpTotal: 0,
|
||
SpIndex: 0,
|
||
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,
|
||
}) {
|
||
final talkPing = TalkPing();
|
||
final payload = talkPing.writeToBuffer();
|
||
ScpMessage message = ScpMessage(
|
||
ProtocolFlag: ProtocolFlagConstant.scp01,
|
||
MessageType: MessageTypeConstant.RealTimeData,
|
||
MessageId: 1,
|
||
SpTotal: 0,
|
||
SpIndex: 0,
|
||
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> talkDataMessage({
|
||
required String FromPeerId,
|
||
required String ToPeerId,
|
||
required TalkData talkData,
|
||
}) {
|
||
final payload = talkData.writeToBuffer();
|
||
ScpMessage message = ScpMessage(
|
||
ProtocolFlag: ProtocolFlagConstant.scp01,
|
||
MessageType: MessageTypeConstant.RealTimeData,
|
||
MessageId: 1,
|
||
SpTotal: 0,
|
||
SpIndex: 0,
|
||
FromPeerId: FromPeerId,
|
||
ToPeerId: ToPeerId,
|
||
Payload: payload,
|
||
PayloadCRC: calculationCrc(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 TalkExpect talkExpect,
|
||
}) {
|
||
final payload = talkExpect.writeToBuffer();
|
||
ScpMessage message = ScpMessage(
|
||
ProtocolFlag: ProtocolFlagConstant.scp01,
|
||
MessageType: MessageTypeConstant.Req,
|
||
MessageId: 1,
|
||
SpTotal: 0,
|
||
SpIndex: 0,
|
||
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,
|
||
}) {
|
||
final genericResp = GenericResp();
|
||
genericResp.message = 'ok';
|
||
genericResp.code = 0;
|
||
final payload = genericResp.writeToBuffer();
|
||
ScpMessage message = ScpMessage(
|
||
ProtocolFlag: ProtocolFlagConstant.scp01,
|
||
MessageType: MessageTypeConstant.Resp,
|
||
MessageId: 1,
|
||
SpTotal: 0,
|
||
SpIndex: 0,
|
||
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,
|
||
}) {
|
||
final genericResp = GenericResp();
|
||
genericResp.message = 'error';
|
||
genericResp.code = -1;
|
||
final payload = genericResp.writeToBuffer();
|
||
ScpMessage message = ScpMessage(
|
||
ProtocolFlag: ProtocolFlagConstant.scp01,
|
||
MessageType: MessageTypeConstant.Resp,
|
||
MessageId: 1,
|
||
SpTotal: 0,
|
||
SpIndex: 0,
|
||
FromPeerId: FromPeerId,
|
||
ToPeerId: ToPeerId,
|
||
Payload: payload,
|
||
PayloadCRC: calculationCrc(payload),
|
||
PayloadLength: payload.length,
|
||
PayloadType: PayloadType,
|
||
);
|
||
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;
|
||
}
|
||
|
||
// 将字符串转换为 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;
|
||
}
|
||
}
|