public static ReadOnlySequence <byte> Serialize(BaseCommand command, MessageMetadata metadata, ReadOnlySequence <byte> payload) { var commandBytes = Serialize <BaseCommand>(command); var commandSizeBytes = ToBigEndianBytes((uint)commandBytes.Length); var metadataBytes = Serialize(metadata); var metadataSizeBytes = ToBigEndianBytes((uint)metadataBytes.Length); var sb = new SequenceBuilder <byte>().Append(metadataSizeBytes).Append(metadataBytes).Append(payload); var checksum = Crc32C.Calculate(sb.Build()); return(sb.Prepend(ToBigEndianBytes(checksum)) .Prepend(Constants.MagicNumber) .Prepend(commandBytes) .Prepend(commandSizeBytes) .Prepend(ToBigEndianBytes((uint)sb.Length)) .Build()); }
private async ValueTask <bool> Validate(MessagePackage messagePackage) { var magicNumberMatches = messagePackage.Data.StartsWith(Constants.MagicNumber); var expectedChecksum = messagePackage.Data.ReadUInt32(2, true); var actualChecksum = Crc32C.Calculate(messagePackage.Data.Slice(6)); if (!magicNumberMatches || expectedChecksum != actualChecksum) { var ack = new CommandAck { Type = CommandAck.AckType.Individual, validation_error = CommandAck.ValidationError.ChecksumMismatch }; ack.MessageIds.Add(messagePackage.MessageId); await Send(ack); return(false); } return(true); }