3using System.Collections.Generic;
16 private const ushort MessageHeaderSize = 6;
17 private readonly
byte[] _originalMessage;
29 _originalMessage = data.ToArray();
34 IsUsingCrc = Convert.ToBoolean(data[4] & 0x04);
35 ushort replyMessageFooterSize = (ushort)(
IsUsingCrc ? 2 : 1);
36 bool isSecureControlBlockPresent = Convert.ToBoolean(data[4] & 0x08);
37 byte secureBlockSize = (byte)(isSecureControlBlockPresent ? data[5] : 0);
39 int messageLength = data.Length - (
IsUsingCrc ? 6 : 5);
40 if (isSecureControlBlockPresent)
42 SecureBlockData = data.Slice(MessageHeaderSize + 1, secureBlockSize - 2).ToArray();
43 Mac = data.Slice(messageLength,
MacSize).ToArray();
48 Payload = data.Slice(MessageHeaderSize + secureBlockSize, data.Length -
49 MessageHeaderSize - secureBlockSize - replyMessageFooterSize -
56 var lastByteIdx =
Payload.Length;
66 throw new Exception(
"The encrypted payload is missing a padding byte");
68 Payload = paddedPayload.AsSpan().Slice(0, lastByteIdx).ToArray();
78 ConvertBytesToUnsignedShort(data.Slice(data.Length - 2, 2))
79 :
CalculateChecksum(data.Slice(0, data.Length - 1).ToArray()) == data[data.Length - 1];
85 var mac = channel.
GenerateMac(data.Slice(0, messageLength).ToArray(),
true);
182 protected override ReadOnlySpan<byte>
Data() =>
Payload.ToArray();
184 private bool IsDataSecure =>
Payload ==
null || Payload.Length == 0 ||
188 private IEnumerable<byte> Mac {
get; }
196 private static IEnumerable<byte> SecureSessionMessages =>
new[]
198 (byte)
SecureChannel.SecurityBlockType.CommandMessageWithNoDataSecurity,
199 (
byte)
SecureChannel.SecurityBlockType.ReplyMessageWithNoDataSecurity,
200 (byte)
SecureChannel.SecurityBlockType.CommandMessageWithDataSecurity,
201 (
byte)
SecureChannel.SecurityBlockType.ReplyMessageWithDataSecurity,
override ReadOnlySpan< byte > Data()
bool IsValidMac
Indicates if the message has a valid MAC signature which was validated via local message channel cont...
bool HasSecureData
Determines whether the incoming message has secure data.
bool IsPayloadDecrypted
Indicates whether the payload was successfully decrypted.
byte Type
Command/reply code of the message.
byte Sequence
Message sequence number.
bool SecureCryptogramHasBeenAccepted()
Checks whether the secure cryptogram has been accepted.
IncomingMessage(ReadOnlySpan< byte > data, IMessageSecureChannel channel)
Creates a new instance of IncomingMessage class.
byte SecurityBlockType
Type of the security block, if there is one.
ReadOnlySpan< byte > OriginalMessageData
Original byte data which includes the header, security control block, payload, MAC and CRC/Checksum s...
bool IsDataCorrect
Gets a value indicating whether the data in the incoming message is correct.
byte[] SecureBlockData
Raw security block bytes.
bool IsUsingCrc
If true, the message has a CRC suffix; otherwise it has a checksum.
bool IsSecureMessage
Indicates if the message was sent via an established secure channel.
bool IsUsingDefaultKey
Gets whether the incoming message is using the default key.
byte[] Payload
Returns the raw message payload.
A base message class for sending or replying.
const ushort MacSize
Size in bytes of MAC signature in message suffix when the secure channel has been established.
const ushort MsgTypeIndex
Index of command/reply code within the message header.
const byte FirstPaddingByte
While padding bytes are generally 0x00, the first byte of padding is not.
MessageType MessageType
Type of message.
byte Address
Address assigned to the device.
static ushort CalculateCrc(ReadOnlySpan< byte > packet)
Calculates the CRC from the packet data.
static byte CalculateChecksum(byte[] packet)
Calculates the checksum from the packet data.
const byte AddressMask
OSDP message address mask.
Represents the secure channel context within which a message is packed/unpacked.
bool IsUsingDefaultKey
Gets a value indicating whether the secure channel is using the default key.
ReadOnlySpan< byte > GenerateMac(ReadOnlySpan< byte > message, bool isIncoming)
Generates a new Message Authentication Code.
byte[] DecodePayload(byte[] payload)
Decodes the payload using the secure channel context.
bool IsSecurityEstablished
Indicates whether or not a secure channel has been established on the current message channel.
@ Command
Command message.