Skip to content

Commit 907d7fa

Browse files
committed
fix(crauth): use 2-byte size and offset in message fragments for osdp_CRAUTH
1 parent 05a2c8a commit 907d7fa

7 files changed

Lines changed: 72 additions & 19 deletions

File tree

src/OSDP.Net/ControlPanel.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,8 @@ private async Task<ReturnReplyData<ManufacturerSpecific>> WaitForManufactureResp
501501
reply = await SendCommand(connectionId, address, new Model.CommandData.ManufacturerSpecific(
502502
manufacturerSpecific.VendorCode, manufactureCommandCode.Concat(
503503
new MessageDataFragment(totalSize, offset, fragmentSize,
504-
manufactureCommandData.Skip(offset).Take(fragmentSize).ToArray()).BuildData()
504+
manufactureCommandData.Skip(offset).Take(fragmentSize).ToArray(),
505+
MessageDataFragmentFieldSize.FourBytes).BuildData()
505506
.ToArray()).ToArray()), cancellationToken)
506507
.ConfigureAwait(false);
507508

@@ -687,7 +688,8 @@ public async Task<bool> EncryptionKeySet(Guid connectionId, byte address,
687688
var reply = await SendCommand(connectionId, address,
688689
new FileTransferFragment(fileType,
689690
new MessageDataFragment(totalSize, offset, nextFragmentSize,
690-
fileData.Skip(offset).Take(nextFragmentSize).ToArray())),
691+
fileData.Skip(offset).Take(nextFragmentSize).ToArray(),
692+
MessageDataFragmentFieldSize.FourBytes)),
691693
cancellationToken, throwOnNak: false)
692694
.ConfigureAwait(false);
693695

@@ -987,7 +989,8 @@ void Handler(object sender, MultiPartMessageDataReplyEventArgs args)
987989
await SendCommand(connectionId, address, new AuthenticationChallengeFragment(
988990
new MessageDataFragment(totalSize, offset, fragmentSize,
989991
requestData.Skip(offset).Take((ushort)Math.Min(fragmentSize, totalSize - offset))
990-
.ToArray())), cancellationToken)
992+
.ToArray(),
993+
MessageDataFragmentFieldSize.TwoBytes)), cancellationToken)
991994
.ConfigureAwait(false);
992995

993996
offset += fragmentSize;

src/OSDP.Net/Model/CommandData/AuthenticationChallengeFragment.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ public override byte[] BuildData()
3434
/// <returns>An instance of AuthenticationChallengeFragment representing the message payload</returns>
3535
public static AuthenticationChallengeFragment ParseData(ReadOnlySpan<byte> data)
3636
{
37-
return new AuthenticationChallengeFragment(MessageDataFragment.ParseData(data));
37+
return new AuthenticationChallengeFragment(MessageDataFragment.ParseData(data, MessageDataFragmentFieldSize.TwoBytes));
3838
}
3939
}

src/OSDP.Net/Model/CommandData/FileTransferFragment.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@ public override byte[] BuildData()
5353
/// <returns>An instance of FileTransferFragment representing the message payload</returns>
5454
public static FileTransferFragment ParseData(ReadOnlySpan<byte> data)
5555
{
56-
return new FileTransferFragment(data[0], MessageDataFragment.ParseData(data.Slice(1)));
56+
return new FileTransferFragment(data[0], MessageDataFragment.ParseData(data.Slice(1), MessageDataFragmentFieldSize.FourBytes));
5757
}
5858
}

src/OSDP.Net/Model/CommandData/MessageDataFragment.cs

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,49 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using OSDP.Net.Messages;
44

55
namespace OSDP.Net.Model.CommandData
66
{
7+
/// <summary>
8+
/// Defines the field size used for the <see cref="MessageDataFragment.TotalSize"/> and
9+
/// <see cref="MessageDataFragment.Offset"/> values.
10+
/// </summary>
11+
public enum MessageDataFragmentFieldSize
12+
{
13+
/// <summary>
14+
/// Use 2-byte unsigned integer fields.
15+
/// </summary>
16+
TwoBytes,
17+
18+
/// <summary>
19+
/// Use 4-byte signed integer fields.
20+
/// </summary>
21+
FourBytes
22+
}
23+
724
/// <summary>
825
/// Represents a fragment of data for a multipart message.
926
/// </summary>
1027
public class MessageDataFragment
1128
{
29+
private readonly MessageDataFragmentFieldSize sizeAndOffsetFieldSize;
30+
1231
/// <summary>
1332
/// Initializes a new instance of the <see cref="MessageDataFragment"/> class.
1433
/// </summary>
1534
/// <param name="totalSize">Total message data size as little-endian format</param>
1635
/// <param name="offset">Offset of the current message</param>
1736
/// <param name="fragmentSize">Size of the fragment</param>
1837
/// <param name="dataFragment">Message fragment data</param>
19-
public MessageDataFragment(int totalSize, int offset, ushort fragmentSize, byte[] dataFragment)
38+
/// <param name="sizeAndOffsetFieldSize">The field size used for <see cref="TotalSize"/> and <see cref="Offset"/>.</param>
39+
public MessageDataFragment(int totalSize, int offset, ushort fragmentSize, byte[] dataFragment,
40+
MessageDataFragmentFieldSize sizeAndOffsetFieldSize)
2041
{
2142
TotalSize = totalSize;
2243
Offset = offset;
2344
FragmentSize = fragmentSize;
2445
DataFragment = dataFragment;
46+
this.sizeAndOffsetFieldSize = sizeAndOffsetFieldSize;
2547
}
2648

2749
/// <summary>
@@ -46,24 +68,52 @@ public MessageDataFragment(int totalSize, int offset, ushort fragmentSize, byte[
4668

4769
internal ReadOnlySpan<byte> BuildData()
4870
{
71+
var useTwoByteFields = sizeAndOffsetFieldSize == MessageDataFragmentFieldSize.TwoBytes;
4972
var data = new List<byte>();
50-
data.AddRange(Message.ConvertIntToBytes(TotalSize));
51-
data.AddRange(Message.ConvertIntToBytes(Offset));
73+
data.AddRange(useTwoByteFields ? Message.ConvertShortToBytes((ushort)TotalSize) : Message.ConvertIntToBytes(TotalSize));
74+
data.AddRange(useTwoByteFields ? Message.ConvertShortToBytes((ushort)Offset) : Message.ConvertIntToBytes(Offset));
5275
data.AddRange(Message.ConvertShortToBytes(FragmentSize));
5376
data.AddRange(DataFragment);
5477
return data.ToArray();
5578
}
5679

5780
/// <summary>Parses the message payload bytes</summary>
5881
/// <param name="data">Message payload as bytes</param>
82+
/// <param name="sizeAndOffsetFieldSize">The field size used for <see cref="TotalSize"/> and <see cref="Offset"/>.</param>
5983
/// <returns>An instance of MessageDataFragment representing the message payload</returns>
60-
public static MessageDataFragment ParseData(ReadOnlySpan<byte> data)
84+
public static MessageDataFragment ParseData(ReadOnlySpan<byte> data,
85+
MessageDataFragmentFieldSize sizeAndOffsetFieldSize)
6186
{
87+
var dataOffset = 0;
88+
89+
var totalSize = ReadValue(sizeAndOffsetFieldSize, data, ref dataOffset);
90+
var offset = ReadValue(sizeAndOffsetFieldSize, data, ref dataOffset);
91+
var fragmentSize = (ushort)ReadValue(MessageDataFragmentFieldSize.TwoBytes, data, ref dataOffset);
92+
var fragmentData = data.Slice(dataOffset).ToArray();
93+
6294
return new MessageDataFragment(
63-
Message.ConvertBytesToInt(data.Slice(0, 4).ToArray()),
64-
Message.ConvertBytesToInt(data.Slice(4, 4).ToArray()),
65-
Message.ConvertBytesToUnsignedShort(data.Slice(8, 2).ToArray()),
66-
data.Slice(10).ToArray());
95+
totalSize,
96+
offset,
97+
fragmentSize,
98+
fragmentData,
99+
sizeAndOffsetFieldSize);
100+
101+
static int ReadValue(MessageDataFragmentFieldSize fieldSize, ReadOnlySpan<byte> data, ref int offset)
102+
{
103+
switch (fieldSize)
104+
{
105+
case MessageDataFragmentFieldSize.TwoBytes:
106+
var twoByteValue = Message.ConvertBytesToUnsignedShort(data.Slice(offset, 2));
107+
offset += 2;
108+
return twoByteValue;
109+
case MessageDataFragmentFieldSize.FourBytes:
110+
var fourByteValue = Message.ConvertBytesToInt(data.Slice(offset, 4).ToArray());
111+
offset += 4;
112+
return fourByteValue;
113+
default:
114+
throw new ArgumentOutOfRangeException(nameof(fieldSize), fieldSize, null);
115+
}
116+
}
67117
}
68118
}
69119
}

src/OSDP.Net/Model/Packet.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22

33
using OSDP.Net.Messages;
44
using OSDP.Net.Model.CommandData;
@@ -153,7 +153,7 @@ public object ParsePayloadData()
153153
case Messages.CommandType.GenerateChallenge:
154154
return null;
155155
case Messages.CommandType.AuthenticateChallenge:
156-
return MessageDataFragment.ParseData(RawPayloadData);
156+
return MessageDataFragment.ParseData(RawPayloadData, MessageDataFragmentFieldSize.TwoBytes);
157157
case Messages.CommandType.KeepActive:
158158
return null;
159159
}

test/OSDP.Net.Tests/Messages/CommandOutgoingMessageTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public string FileTransferBuildMessage_TestCases(DeviceProxy device)
107107
device.MessageControl.IncrementSequence(1);
108108

109109
var outgoingMessage = new OutgoingMessage(device.Address, device.MessageControl,
110-
new FileTransferFragment(3, new MessageDataFragment(1000, 10, 5, new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05 })));
110+
new FileTransferFragment(3, new MessageDataFragment(1000, 10, 5, new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05 }, MessageDataFragmentFieldSize.FourBytes)));
111111

112112
return BitConverter.ToString(outgoingMessage.BuildMessage(CreateSecureChannel(device.UseSecureChannel)));
113113
}

test/OSDP.Net.Tests/Model/CommandData/FileTransferFragmentTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using NUnit.Framework;
1+
using NUnit.Framework;
22
using OSDP.Net.Messages;
33
using OSDP.Net.Messages.SecureChannel;
44
using OSDP.Net.Model.CommandData;
@@ -13,7 +13,7 @@ internal class FileTransferFragmentTest
1313
0x01, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x09, 0x08, 0x07, 0x06, 0x05
1414
];
1515

16-
private FileTransferFragment TestFileTransferFragment => new(0x01, new MessageDataFragment(10, 0, 5, [0x09, 0x08, 0x07, 0x06, 0x05]));
16+
private FileTransferFragment TestFileTransferFragment => new(0x01, new MessageDataFragment(10, 0, 5, [0x09, 0x08, 0x07, 0x06, 0x05], MessageDataFragmentFieldSize.FourBytes));
1717

1818
[Test]
1919
public void CheckConstantValues()

0 commit comments

Comments
 (0)